diff --git a/web/src/pages/Explore.tsx b/web/src/pages/Explore.tsx
index c10b365b..acd1964b 100644
--- a/web/src/pages/Explore.tsx
+++ b/web/src/pages/Explore.tsx
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslate } from "@/utils/i18n";
import { useLocation } from "react-router-dom";
-import { useFilterStore, useMemoStore } from "@/store/module";
+import { useFilterStore, useMemoStore, useUserStore } from "@/store/module";
import { TAG_REG } from "@/labs/marked/parser";
import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
import useLoading from "@/hooks/useLoading";
@@ -16,24 +16,16 @@ const Explore = () => {
const location = useLocation();
const filterStore = useFilterStore();
const memoStore = useMemoStore();
+ const userStore = useUserStore();
const filter = filterStore.state;
- const memos = memoStore.state.memos;
+ const { memos } = memoStore.state;
const [isComplete, setIsComplete] = useState
(false);
const loadingState = useLoading();
- useEffect(() => {
- memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, 0).then((memos) => {
- if (memos.length < DEFAULT_MEMO_LIMIT) {
- setIsComplete(true);
- }
- loadingState.setFinish();
- });
- }, [location]);
-
const { tag: tagQuery, text: textQuery } = filter;
const showMemoFilter = Boolean(tagQuery || textQuery);
- const shownMemos = showMemoFilter
+ const fetchedMemos = showMemoFilter
? memos.filter((memo) => {
let shouldShow = true;
@@ -57,13 +49,35 @@ const Explore = () => {
})
: memos;
- const sortedMemos = shownMemos
+ const username = userStore.getUsernameFromPath();
+ let sortedMemos = fetchedMemos
.filter((m) => m.rowStatus === "NORMAL" && m.visibility !== "PRIVATE")
.sort((mi, mj) => mj.displayTs - mi.displayTs);
+ if (username != undefined) {
+ sortedMemos = sortedMemos.filter((m) => m.creatorUsername === username);
+ }
+
+ useEffect(() => {
+ const username = userStore.getUsernameFromPath();
+ memoStore
+ .fetchAllMemos(DEFAULT_MEMO_LIMIT, 0, username)
+ .then((fetchedMemos) => {
+ if (fetchedMemos.length < DEFAULT_MEMO_LIMIT) {
+ setIsComplete(true);
+ }
+ loadingState.setFinish();
+ })
+ .catch((error) => {
+ console.error(error);
+ toast.error(error.response.data.message);
+ });
+ }, [location]);
+
const handleFetchMoreClick = async () => {
try {
- const fetchedMemos = await memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, memos.length);
+ const username = userStore.getUsernameFromPath();
+ const fetchedMemos = await memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, memos.length, username);
if (fetchedMemos.length < DEFAULT_MEMO_LIMIT) {
setIsComplete(true);
} else {
diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx
index eba2645a..f69939c5 100644
--- a/web/src/pages/Home.tsx
+++ b/web/src/pages/Home.tsx
@@ -15,14 +15,14 @@ function Home() {
const user = userStore.state.user;
useEffect(() => {
- const currentUserId = userStore.getCurrentUserId();
- userStore.getUserById(currentUserId).then((user) => {
+ const currentUsername = userStore.getCurrentUsername();
+ userStore.getUserByUsername(currentUsername).then((user) => {
if (!user) {
toast.error(t("message.user-not-found"));
return;
}
});
- }, [userStore.getCurrentUserId()]);
+ }, [userStore.getCurrentUsername()]);
useEffect(() => {
if (user?.setting.locale) {
diff --git a/web/src/router/index.tsx b/web/src/router/index.tsx
index 256bb0ed..d155b042 100644
--- a/web/src/router/index.tsx
+++ b/web/src/router/index.tsx
@@ -63,22 +63,25 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
+ const { user } = store.getState().user;
const { systemStatus } = store.getState().global;
- if (isNullorUndefined(host)) {
- return redirect("/auth");
- } else if (isNullorUndefined(user) && !systemStatus.disablePublicMemos) {
- return redirect("/explore");
- } else if (isNullorUndefined(user) && systemStatus.disablePublicMemos) {
+ // if user is authenticated, then show home
+ if (!isNullorUndefined(user)) {
+ return null;
+ }
+
+ // if user is anonymous, then redirect to auth if disabled public memos, else redirect to explore
+ if (systemStatus.disablePublicMemos) {
return redirect("/auth");
}
- return null;
+
+ return redirect("/explore");
},
},
{
- path: "/u/:userId",
- element: ,
+ path: "/u/:username",
+ element: ,
loader: async () => {
await initialGlobalStateLoader();
@@ -88,12 +91,13 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
+ const { user } = store.getState().user;
const { systemStatus } = store.getState().global;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user) && systemStatus.disablePublicMemos) {
return redirect("/auth");
}
+
return null;
},
},
@@ -109,10 +113,10 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
+ const { user } = store.getState().user;
const { systemStatus } = store.getState().global;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user) && systemStatus.disablePublicMemos) {
return redirect("/auth");
}
return null;
@@ -130,10 +134,9 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
- const { systemStatus } = store.getState().global;
+ const { user } = store.getState().user;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user)) {
return redirect("/auth");
}
return null;
@@ -151,10 +154,9 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
- const { systemStatus } = store.getState().global;
+ const { user } = store.getState().user;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user)) {
return redirect("/auth");
}
return null;
@@ -172,10 +174,9 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
- const { systemStatus } = store.getState().global;
+ const { user } = store.getState().user;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user)) {
return redirect("/auth");
}
return null;
@@ -194,10 +195,9 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
- const { systemStatus } = store.getState().global;
+ const { user } = store.getState().user;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user)) {
return redirect("/auth");
}
return null;
@@ -215,10 +215,9 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
- const { systemStatus } = store.getState().global;
+ const { user } = store.getState().user;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user)) {
return redirect("/auth");
}
return null;
@@ -238,10 +237,10 @@ const router = createBrowserRouter([
// do nth
}
- const { host, user } = store.getState().user;
+ const { user } = store.getState().user;
const { systemStatus } = store.getState().global;
- if (isNullorUndefined(host) || (isNullorUndefined(user) && systemStatus.disablePublicMemos)) {
+ if (isNullorUndefined(user) && systemStatus.disablePublicMemos) {
return redirect("/auth");
}
return null;
diff --git a/web/src/store/module/global.ts b/web/src/store/module/global.ts
index d1f5dfc5..f8467cda 100644
--- a/web/src/store/module/global.ts
+++ b/web/src/store/module/global.ts
@@ -65,6 +65,9 @@ export const useGlobalStore = () => {
getState: () => {
return store.getState().global;
},
+ getDisablePublicMemos: () => {
+ return store.getState().global.systemStatus.disablePublicMemos;
+ },
isDev: () => {
return state.systemStatus.profile.mode !== "prod";
},
diff --git a/web/src/store/module/memo.ts b/web/src/store/module/memo.ts
index b246ff3f..a8a6942f 100644
--- a/web/src/store/module/memo.ts
+++ b/web/src/store/module/memo.ts
@@ -41,7 +41,7 @@ export const useMemoStore = () => {
offset,
};
if (userStore.isVisitorMode()) {
- memoFind.creatorId = userStore.getUserIdFromPath();
+ memoFind.creatorUsername = userStore.getUsernameFromPath();
}
const { data } = await api.getMemoList(memoFind);
const fetchedMemos = data.map((m) => convertResponseModelMemo(m));
@@ -54,16 +54,22 @@ export const useMemoStore = () => {
return fetchedMemos;
},
- fetchAllMemos: async (limit = DEFAULT_MEMO_LIMIT, offset?: number) => {
+ fetchAllMemos: async (limit = DEFAULT_MEMO_LIMIT, offset?: number, username?: string) => {
+ store.dispatch(setIsFetching(true));
const memoFind: MemoFind = {
rowStatus: "NORMAL",
limit,
offset,
};
+ if (username != undefined) {
+ memoFind.creatorUsername = username;
+ }
+
const { data } = await api.getAllMemos(memoFind);
const fetchedMemos = data.map((m) => convertResponseModelMemo(m));
store.dispatch(upsertMemos(fetchedMemos));
+ store.dispatch(setIsFetching(false));
for (const m of fetchedMemos) {
memoCacheStore.setMemoCache(m);
@@ -76,7 +82,7 @@ export const useMemoStore = () => {
rowStatus: "ARCHIVED",
};
if (userStore.isVisitorMode()) {
- memoFind.creatorId = userStore.getUserIdFromPath();
+ memoFind.creatorUsername = userStore.getUsernameFromPath();
}
const { data } = await api.getMemoList(memoFind);
const archivedMemos = data.map((m) => {
diff --git a/web/src/store/module/tag.ts b/web/src/store/module/tag.ts
index 154f023d..737b3f81 100644
--- a/web/src/store/module/tag.ts
+++ b/web/src/store/module/tag.ts
@@ -14,7 +14,7 @@ export const useTagStore = () => {
fetchTags: async () => {
const tagFind: TagFind = {};
if (userStore.isVisitorMode()) {
- tagFind.creatorId = userStore.getUserIdFromPath();
+ tagFind.creatorUsername = userStore.getUsernameFromPath();
}
const { data } = await api.getTagList(tagFind);
store.dispatch(setTags(data));
diff --git a/web/src/store/module/user.ts b/web/src/store/module/user.ts
index bef95185..38f5bd25 100644
--- a/web/src/store/module/user.ts
+++ b/web/src/store/module/user.ts
@@ -1,7 +1,7 @@
import { camelCase } from "lodash-es";
import * as api from "@/helpers/api";
import storage from "@/helpers/storage";
-import { UNKNOWN_ID } from "@/helpers/consts";
+import { UNKNOWN_USERNAME } from "@/helpers/consts";
import { getSystemColorScheme } from "@/helpers/utils";
import store, { useAppSelector } from "..";
import { setAppearance, setLocale } from "../reducer/global";
@@ -82,6 +82,16 @@ const getUserIdFromPath = () => {
return undefined;
};
+const getUsernameFromPath = () => {
+ const pathname = window.location.pathname;
+ const usernameRegex = /^\/u\/(\w+).*/;
+ const result = pathname.match(usernameRegex);
+ if (result && result.length === 2) {
+ return String(result[1]);
+ }
+ return undefined;
+};
+
const doSignIn = async () => {
const { data: user } = await api.getMyselfUser();
if (user) {
@@ -100,7 +110,7 @@ export const useUserStore = () => {
const state = useAppSelector((state) => state.user);
const isVisitorMode = () => {
- return state.user === undefined || (getUserIdFromPath() && state.user.id !== getUserIdFromPath());
+ return state.user === undefined || (getUsernameFromPath() && state.user.username !== getUsernameFromPath());
};
return {
@@ -110,17 +120,18 @@ export const useUserStore = () => {
},
isVisitorMode,
getUserIdFromPath,
+ getUsernameFromPath,
doSignIn,
doSignOut,
- getCurrentUserId: () => {
+ getCurrentUsername: () => {
if (isVisitorMode()) {
- return getUserIdFromPath() || UNKNOWN_ID;
+ return getUsernameFromPath() || UNKNOWN_USERNAME;
} else {
- return state.user?.id || UNKNOWN_ID;
+ return state.user?.username || UNKNOWN_USERNAME;
}
},
- getUserById: async (userId: UserId) => {
- const { data } = await api.getUserById(userId);
+ getUserByUsername: async (username: string) => {
+ const { data } = await api.getUserByUsername(username);
if (data) {
const user = convertResponseModelUser(data);
store.dispatch(setUserById(user));
diff --git a/web/src/types/modules/memo.d.ts b/web/src/types/modules/memo.d.ts
index b3f95c1c..f09f4ce4 100644
--- a/web/src/types/modules/memo.d.ts
+++ b/web/src/types/modules/memo.d.ts
@@ -5,7 +5,7 @@ type Visibility = "PUBLIC" | "PROTECTED" | "PRIVATE";
interface Memo {
id: MemoId;
- creatorId: UserId;
+ creatorUsername: string;
createdTs: TimeStamp;
updatedTs: TimeStamp;
rowStatus: RowStatus;
@@ -38,7 +38,7 @@ interface MemoPatch {
}
interface MemoFind {
- creatorId?: UserId;
+ creatorUsername?: string;
rowStatus?: RowStatus;
pinned?: boolean;
visibility?: Visibility;
diff --git a/web/src/types/modules/shortcut.d.ts b/web/src/types/modules/shortcut.d.ts
index c8ff0685..02c58a08 100644
--- a/web/src/types/modules/shortcut.d.ts
+++ b/web/src/types/modules/shortcut.d.ts
@@ -3,7 +3,7 @@ type ShortcutId = number;
interface Shortcut {
id: ShortcutId;
- creatorId: UserId;
+ creatorUsername: string;
rowStatus: RowStatus;
createdTs: TimeStamp;
updatedTs: TimeStamp;
@@ -25,5 +25,5 @@ interface ShortcutPatch {
}
interface ShortcutFind {
- creatorId?: UserId;
+ creatorUsername?: string;
}
diff --git a/web/src/types/modules/tag.d.ts b/web/src/types/modules/tag.d.ts
index 3e45f16c..beda8fca 100644
--- a/web/src/types/modules/tag.d.ts
+++ b/web/src/types/modules/tag.d.ts
@@ -1,3 +1,3 @@
interface TagFind {
- creatorId?: UserId;
+ creatorUsername?: string;
}