Skip to content

Commit

Permalink
refactor: user v1 store (#2047)
Browse files Browse the repository at this point in the history
  • Loading branch information
boojack authored Jul 29, 2023
1 parent f5793c1 commit a6a1898
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 46 deletions.
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"i18next": "^21.9.2",
"i18next-browser-languagedetector": "^7.0.1",
"lodash-es": "^4.17.21",
"lucide-react": "^0.105.0",
"lucide-react": "^0.263.0",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
8 changes: 4 additions & 4 deletions web/pnpm-lock.yaml

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

25 changes: 19 additions & 6 deletions web/src/components/Memo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Link } from "react-router-dom";
import { useFilterStore, useMemoStore, useUserStore } from "@/store/module";
import { UNKNOWN_ID } from "@/helpers/consts";
import { getRelativeTimeString } from "@/helpers/datetime";
import { useMemoCacheStore } from "@/store/zustand";
import { useMemoCacheStore, useUserV1Store } from "@/store/v1";
import { showCommonDialog } from "./Dialog/CommonDialog";
import Icon from "./Icon";
import MemoContent from "./MemoContent";
Expand All @@ -18,6 +18,7 @@ import showShareMemo from "./ShareMemoDialog";
import showPreviewImageDialog from "./PreviewImageDialog";
import showChangeMemoCreatedTsDialog from "./ChangeMemoCreatedTsDialog";
import showMemoEditorDialog from "./MemoEditor/MemoEditorDialog";
import UserAvatar from "./UserAvatar";
import "@/less/memo.less";

interface Props {
Expand All @@ -36,11 +37,19 @@ const Memo: React.FC<Props> = (props: Props) => {
const userStore = useUserStore();
const memoStore = useMemoStore();
const memoCacheStore = useMemoCacheStore();
const userV1Store = useUserV1Store();
const [createdTimeStr, setCreatedTimeStr] = useState<string>(getRelativeTimeString(memo.displayTs));
const [relatedMemoList, setRelatedMemoList] = useState<Memo[]>([]);
const memoContainerRef = useRef<HTMLDivElement>(null);
const readonly = userStore.isVisitorMode() || userStore.getCurrentUsername() !== memo.creatorUsername;
const creator = userV1Store.getUserByUsername(memo.creatorUsername);

// Prepare memo creator.
useEffect(() => {
userV1Store.getOrFetchUserByUsername(memo.creatorUsername);
}, [memo.creatorUsername]);

// Prepare related memos.
useEffect(() => {
Promise.allSettled(memo.relationList.map((memoRelation) => memoCacheStore.getOrFetchMemoById(memoRelation.relatedMemoId))).then(
(results) => {
Expand Down Expand Up @@ -217,14 +226,18 @@ const Memo: React.FC<Props> = (props: Props) => {
<div className={`memo-wrapper ${"memos-" + memo.id} ${memo.pinned && !readonly ? "pinned" : ""}`} ref={memoContainerRef}>
<div className="memo-top-wrapper">
<div className="status-text-container">
{showCreator && creator && (
<>
<Link className="flex flex-row justify-start items-center" to={`/u/${memo.creatorUsername}`}>
<UserAvatar className="!w-5 !h-auto mr-1" avatarUrl={creator.avatarUrl} />
<span className="text-sm text-gray-600 dark:text-zinc-300">{creator.nickname}</span>
</Link>
<Icon.Dot className="w-4 h-auto text-gray-400 dark:text-zinc-400" />
</>
)}
<Link className="time-text" to={`/m/${memo.id}`} onClick={handleMemoCreatedTimeClick}>
{createdTimeStr}
</Link>
{showCreator && (
<Link className="name-text" to={`/u/${memo.creatorUsername}`}>
@{memo.creatorName}
</Link>
)}
</div>
<div className="btns-container space-x-2">
{showVisibility && memo.visibility !== "PRIVATE" && (
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/MemoChat/ChatMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Message } from "@/store/zustand/message";
import { Message } from "@/store/v1/message";
import { marked } from "@/labs/marked";
import Icon from "@/components/Icon";
import Dropdown from "../kit/Dropdown";
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/MemoChat/ConversationTab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Conversation } from "@/store/zustand/conversation";
import { Conversation } from "@/store/v1/conversation";
import Icon from "@/components/Icon";

interface ConversationTabProps {
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/MemoEditor/RelationListView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { useMemoCacheStore } from "@/store/zustand";
import { useMemoCacheStore } from "@/store/v1";
import Icon from "../Icon";

interface Props {
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/MemoRelationListView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { useMemoCacheStore } from "@/store/zustand";
import { useMemoCacheStore } from "@/store/v1";
import Icon from "./Icon";

interface Props {
Expand Down
4 changes: 3 additions & 1 deletion web/src/components/UserAvatar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import classNames from "classnames";

interface Props {
avatarUrl?: string;
className?: string;
Expand All @@ -6,7 +8,7 @@ interface Props {
const UserAvatar = (props: Props) => {
const { avatarUrl, className } = props;
return (
<div className={`${className ?? ""} w-8 h-8 overflow-clip`}>
<div className={classNames(`w-8 h-8 overflow-clip`, className)}>
<img className="w-full h-auto rounded-full min-w-full min-h-full object-cover" src={avatarUrl || "/logo.webp"} alt="" />
</div>
);
Expand Down
25 changes: 1 addition & 24 deletions web/src/helpers/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import axios from "axios";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { Message } from "@/store/zustand/message";

export function getSystemStatus() {
return axios.get<SystemStatus>("/api/v1/status");
Expand Down Expand Up @@ -139,32 +137,11 @@ export function unpinMemo(memoId: MemoId) {
export function deleteMemo(memoId: MemoId) {
return axios.delete(`/api/v1/memo/${memoId}`);
}

export function checkOpenAIEnabled() {
return axios.get<boolean>(`/api/openai/enabled`);
}

export async function chatStreaming(messageList: Array<Message>, onmessage: any, onclose: any) {
await fetchEventSource("/api/v1/openai/chat-streaming", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(messageList),
async onopen() {
// to do nth
},
onmessage(event: any) {
onmessage(event);
},
onclose() {
onclose();
},
onerror(error: any) {
console.log("error", error);
},
});
}

export function getShortcutList(shortcutFind?: ShortcutFind) {
const queryList = [];
if (shortcutFind?.creatorUsername) {
Expand Down
29 changes: 26 additions & 3 deletions web/src/pages/MemoChat.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Button, Stack } from "@mui/joy";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { head } from "lodash-es";
import React, { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslate } from "@/utils/i18n";
import * as api from "@/helpers/api";
import useLoading from "@/hooks/useLoading";
import { useMessageStore } from "@/store/zustand/message";
import { Conversation, useConversationStore } from "@/store/zustand/conversation";
import { Message, useMessageStore } from "@/store/v1/message";
import { Conversation, useConversationStore } from "@/store/v1/conversation";
import Icon from "@/components/Icon";
import { generateUUID } from "@/utils/uuid";
import MobileHeader from "@/components/MobileHeader";
Expand All @@ -15,6 +16,28 @@ import ChatInput from "@/components/MemoChat/ChatInput";
import ConversationTab from "@/components/MemoChat/ConversationTab";
import Empty from "@/components/Empty";

const chatStreaming = async (messageList: Array<Message>, onmessage: any, onclose: any) => {
await fetchEventSource("/api/v1/openai/chat-streaming", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(messageList),
async onopen() {
// to do nth
},
onmessage(event: any) {
onmessage(event);
},
onclose() {
onclose();
},
onerror(error: any) {
console.log("error", error);
},
});
};

const MemoChat = () => {
const t = useTranslate();
const fetchingState = useLoading(false);
Expand Down Expand Up @@ -91,7 +114,7 @@ const MemoChat = () => {

const fetchChatStreaming = async (messageId: string) => {
const messageList = messageStore.getState().messageList;
await api.chatStreaming(
await chatStreaming(
messageList,
async (event: any) => {
messageStore.updateMessage(messageId, event.data);
Expand Down
2 changes: 1 addition & 1 deletion web/src/store/module/memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
import { useUserStore } from "./";
import store, { useAppSelector } from "../";
import { createMemo, deleteMemo, patchMemo, setIsFetching, upsertMemos } from "../reducer/memo";
import { useMemoCacheStore } from "../zustand/memo";
import { useMemoCacheStore } from "../v1";

export const convertResponseModelMemo = (memo: Memo): Memo => {
return {
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions web/src/store/v1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import useMemoCacheStore from "./memo";
import useUserV1Store from "./user";

export { useUserV1Store, useMemoCacheStore };
4 changes: 3 additions & 1 deletion web/src/store/zustand/memo.ts → web/src/store/v1/memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { combine } from "zustand/middleware";
import * as api from "@/helpers/api";
import { convertResponseModelMemo } from "../module";

export const useMemoCacheStore = create(
const useMemoCacheStore = create(
combine({ memoById: new Map<MemoId, Memo>() }, (set, get) => ({
getState: () => get(),
getOrFetchMemoById: async (memoId: MemoId) => {
Expand Down Expand Up @@ -39,3 +39,5 @@ export const useMemoCacheStore = create(
},
}))
);

export default useMemoCacheStore;
File renamed without changes.
31 changes: 31 additions & 0 deletions web/src/store/v1/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { create } from "zustand";
import * as api from "@/helpers/api";
import { convertResponseModelUser } from "../module";

interface UserV1Store {
userMapByUsername: Record<string, User>;
getOrFetchUserByUsername: (username: string) => Promise<User>;
getUserByUsername: (username: string) => User;
}

const useUserV1Store = create<UserV1Store>()((set, get) => ({
userMapByUsername: {},
getOrFetchUserByUsername: async (username: string) => {
const userMap = get().userMapByUsername;
if (userMap[username]) {
return userMap[username] as User;
}

const { data } = await api.getUserByUsername(username);
const user = convertResponseModelUser(data);
userMap[username] = user;
set(userMap);
return user;
},
getUserByUsername: (username: string) => {
const userMap = get().userMapByUsername;
return userMap[username] as User;
},
}));

export default useUserV1Store;
1 change: 0 additions & 1 deletion web/src/store/zustand/index.ts

This file was deleted.

0 comments on commit a6a1898

Please sign in to comment.