mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: update user store
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import { memo, useEffect, useRef, useState } from "react";
|
import { memo, useEffect, useRef, useState } from "react";
|
||||||
import { escape, indexOf } from "lodash-es";
|
import { escape, indexOf } from "lodash-es";
|
||||||
import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts";
|
import { IMAGE_URL_REG, LINK_URL_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts";
|
||||||
import * as utils from "../helpers/utils";
|
import * as utils from "../helpers/utils";
|
||||||
import { DONE_BLOCK_REG, parseMarkedToHtml, TODO_BLOCK_REG } from "../helpers/marked";
|
import { DONE_BLOCK_REG, parseMarkedToHtml, TODO_BLOCK_REG } from "../helpers/marked";
|
||||||
import { editorStateService, locationService, memoService, userService } from "../services";
|
import { editorStateService, locationService, memoService, userService } from "../services";
|
||||||
@ -229,9 +229,9 @@ export function formatMemoContent(content: string) {
|
|||||||
|
|
||||||
return tempElement.innerHTML
|
return tempElement.innerHTML
|
||||||
.replace(IMAGE_URL_REG, "")
|
.replace(IMAGE_URL_REG, "")
|
||||||
.replace(TAG_REG, "<span class='tag-span'>#$1</span> ")
|
.replace(MEMO_LINK_REG, "<span class='memo-link-text' data-value='$2'>$1</span>")
|
||||||
.replace(LINK_REG, "<a class='link' target='_blank' rel='noreferrer' href='$1'>$1</a>")
|
.replace(LINK_URL_REG, "<a class='link' target='_blank' rel='noreferrer' href='$2'>$1</a>")
|
||||||
.replace(MEMO_LINK_REG, "<span class='memo-link-text' data-value='$2'>$1</span>");
|
.replace(TAG_REG, "<span class='tag-span'>#$1</span> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(Memo);
|
export default memo(Memo);
|
||||||
|
@ -28,7 +28,7 @@ const MemoEditor: React.FC<Props> = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorState.markMemoId && editorState.markMemoId !== UNKNOWN_ID) {
|
if (editorState.markMemoId && editorState.markMemoId !== UNKNOWN_ID) {
|
||||||
const editorCurrentValue = editorRef.current?.getContent();
|
const editorCurrentValue = editorRef.current?.getContent();
|
||||||
const memoLinkText = `${editorCurrentValue ? "\n" : ""}Mark: [@MEMO](${editorState.markMemoId})`;
|
const memoLinkText = `${editorCurrentValue ? "\n" : ""}Mark: @[MEMO](${editorState.markMemoId})`;
|
||||||
editorRef.current?.insertText(memoLinkText);
|
editorRef.current?.insertText(memoLinkText);
|
||||||
editorStateService.clearMarkMemo();
|
editorStateService.clearMarkMemo();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { memoService, shortcutService } from "../services";
|
import { memoService, shortcutService } from "../services";
|
||||||
import { useAppSelector } from "../store";
|
import { useAppSelector } from "../store";
|
||||||
import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG } from "../helpers/consts";
|
import { IMAGE_URL_REG, LINK_URL_REG, MEMO_LINK_REG, TAG_REG } from "../helpers/consts";
|
||||||
import * as utils from "../helpers/utils";
|
import * as utils from "../helpers/utils";
|
||||||
import { checkShouldShowMemoWithFilters } from "../helpers/filter";
|
import { checkShouldShowMemoWithFilters } from "../helpers/filter";
|
||||||
import toastHelper from "./Toast";
|
import toastHelper from "./Toast";
|
||||||
@ -58,7 +58,7 @@ const MemoList: React.FC<Props> = () => {
|
|||||||
if (memoType) {
|
if (memoType) {
|
||||||
if (memoType === "NOT_TAGGED" && memo.content.match(TAG_REG) !== null) {
|
if (memoType === "NOT_TAGGED" && memo.content.match(TAG_REG) !== null) {
|
||||||
shouldShow = false;
|
shouldShow = false;
|
||||||
} else if (memoType === "LINKED" && memo.content.match(LINK_REG) === null) {
|
} else if (memoType === "LINKED" && memo.content.match(LINK_URL_REG) === null) {
|
||||||
shouldShow = false;
|
shouldShow = false;
|
||||||
} else if (memoType === "IMAGED" && memo.content.match(IMAGE_URL_REG) === null) {
|
} else if (memoType === "IMAGED" && memo.content.match(IMAGE_URL_REG) === null) {
|
||||||
shouldShow = false;
|
shouldShow = false;
|
||||||
|
@ -3,14 +3,13 @@ import * as utils from "../helpers/utils";
|
|||||||
import userService from "../services/userService";
|
import userService from "../services/userService";
|
||||||
import { locationService } from "../services";
|
import { locationService } from "../services";
|
||||||
import { useAppSelector } from "../store";
|
import { useAppSelector } from "../store";
|
||||||
import toastHelper from "./Toast";
|
|
||||||
import MenuBtnsPopup from "./MenuBtnsPopup";
|
import MenuBtnsPopup from "./MenuBtnsPopup";
|
||||||
import "../less/user-banner.less";
|
import "../less/user-banner.less";
|
||||||
|
|
||||||
interface Props {}
|
interface Props {}
|
||||||
|
|
||||||
const UserBanner: React.FC<Props> = () => {
|
const UserBanner: React.FC<Props> = () => {
|
||||||
const user = useAppSelector((state) => state.user.user);
|
const { user, owner } = useAppSelector((state) => state.user);
|
||||||
const { memos, tags } = useAppSelector((state) => state.memo);
|
const { memos, tags } = useAppSelector((state) => state.memo);
|
||||||
const [shouldShowPopupBtns, setShouldShowPopupBtns] = useState(false);
|
const [shouldShowPopupBtns, setShouldShowPopupBtns] = useState(false);
|
||||||
const [username, setUsername] = useState("Memos");
|
const [username, setUsername] = useState("Memos");
|
||||||
@ -18,24 +17,15 @@ const UserBanner: React.FC<Props> = () => {
|
|||||||
const isVisitorMode = userService.isVisitorMode();
|
const isVisitorMode = userService.isVisitorMode();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentUserId = userService.getUserIdFromPath();
|
if (isVisitorMode) {
|
||||||
if (isVisitorMode && currentUserId) {
|
if (!owner) {
|
||||||
userService
|
return;
|
||||||
.getUserById(currentUserId)
|
}
|
||||||
.then((user) => {
|
setUsername(owner.name);
|
||||||
if (user) {
|
setCreatedDays(Math.ceil((Date.now() - utils.getTimeStampByDate(owner.createdTs)) / 1000 / 3600 / 24));
|
||||||
setUsername(user.name);
|
|
||||||
setCreatedDays(user ? Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24) : 0);
|
|
||||||
} else {
|
|
||||||
toastHelper.error("User not found");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// do nth
|
|
||||||
});
|
|
||||||
} else if (user) {
|
} else if (user) {
|
||||||
setUsername(user.name);
|
setUsername(user.name);
|
||||||
setCreatedDays(user ? Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24) : 0);
|
setCreatedDays(Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24));
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@ export const DAILY_TIMESTAMP = 3600 * 24 * 1000;
|
|||||||
// tag regex
|
// tag regex
|
||||||
export const TAG_REG = /#(.+?) /g;
|
export const TAG_REG = /#(.+?) /g;
|
||||||
|
|
||||||
// URL regex
|
// markdown image regex
|
||||||
export const LINK_REG = /(https?:\/\/[^\s<\\*>']+)/g;
|
|
||||||
|
|
||||||
// image regex
|
|
||||||
export const IMAGE_URL_REG = /!\[.*?\]\((.+?)\)/g;
|
export const IMAGE_URL_REG = /!\[.*?\]\((.+?)\)/g;
|
||||||
|
|
||||||
|
// markdown link regex
|
||||||
|
export const LINK_URL_REG = /\[(.*?)\]\((.+?)\)/g;
|
||||||
|
|
||||||
// linked memo regex
|
// linked memo regex
|
||||||
export const MEMO_LINK_REG = /\[@(.+?)\]\((.+?)\)/g;
|
export const MEMO_LINK_REG = /@\[(.+?)\]\((.+?)\)/g;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG } from "./consts";
|
import { IMAGE_URL_REG, LINK_URL_REG, MEMO_LINK_REG, TAG_REG } from "./consts";
|
||||||
|
|
||||||
export const relationConsts = [
|
export const relationConsts = [
|
||||||
{ text: "And", value: "AND" },
|
{ text: "And", value: "AND" },
|
||||||
@ -142,7 +142,7 @@ export const checkShouldShowMemo = (memo: Memo, filter: Filter) => {
|
|||||||
let matched = false;
|
let matched = false;
|
||||||
if (value === "NOT_TAGGED" && memo.content.match(TAG_REG) === null) {
|
if (value === "NOT_TAGGED" && memo.content.match(TAG_REG) === null) {
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (value === "LINKED" && memo.content.match(LINK_REG) !== null) {
|
} else if (value === "LINKED" && memo.content.match(LINK_URL_REG) !== null) {
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (value === "IMAGED" && memo.content.match(IMAGE_URL_REG) !== null) {
|
} else if (value === "IMAGED" && memo.content.match(IMAGE_URL_REG) !== null) {
|
||||||
matched = true;
|
matched = true;
|
||||||
|
@ -15,19 +15,22 @@ function Home() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
userService
|
userService
|
||||||
.doSignIn()
|
.initialState()
|
||||||
.catch()
|
.catch()
|
||||||
.finally(async () => {
|
.finally(async () => {
|
||||||
if (!userService.getState().user) {
|
const { host, owner, user } = userService.getState();
|
||||||
if (userService.isVisitorMode()) {
|
if (!host) {
|
||||||
const currentUserId = userService.getUserIdFromPath() as number;
|
locationService.replaceHistory("/signin");
|
||||||
const user = await userService.getUserById(currentUserId);
|
return;
|
||||||
if (!user) {
|
}
|
||||||
toastHelper.error("User not found");
|
|
||||||
}
|
if (userService.isVisitorMode()) {
|
||||||
} else {
|
if (!owner) {
|
||||||
locationService.replaceHistory("/signin");
|
toastHelper.error("User not found");
|
||||||
return;
|
}
|
||||||
|
} else {
|
||||||
|
if (!user) {
|
||||||
|
locationService.replaceHistory(`/u/${host.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadingState.setFinish();
|
loadingState.setFinish();
|
||||||
|
@ -17,9 +17,10 @@ const memoService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
fetchAllMemos: async () => {
|
fetchAllMemos: async () => {
|
||||||
const memoFind: MemoFind = {
|
const memoFind: MemoFind = {};
|
||||||
creatorId: userService.getUserIdFromPath(),
|
if (userService.isVisitorMode()) {
|
||||||
};
|
memoFind.creatorId = userService.getUserIdFromPath();
|
||||||
|
}
|
||||||
const { data } = (await api.getMemoList(memoFind)).data;
|
const { data } = (await api.getMemoList(memoFind)).data;
|
||||||
const memos = data.filter((m) => m.rowStatus !== "ARCHIVED").map((m) => convertResponseModelMemo(m));
|
const memos = data.filter((m) => m.rowStatus !== "ARCHIVED").map((m) => convertResponseModelMemo(m));
|
||||||
store.dispatch(setMemos(memos));
|
store.dispatch(setMemos(memos));
|
||||||
@ -29,9 +30,11 @@ const memoService = {
|
|||||||
|
|
||||||
fetchArchivedMemos: async () => {
|
fetchArchivedMemos: async () => {
|
||||||
const memoFind: MemoFind = {
|
const memoFind: MemoFind = {
|
||||||
creatorId: userService.getUserIdFromPath(),
|
|
||||||
rowStatus: "ARCHIVED",
|
rowStatus: "ARCHIVED",
|
||||||
};
|
};
|
||||||
|
if (userService.isVisitorMode()) {
|
||||||
|
memoFind.creatorId = userService.getUserIdFromPath();
|
||||||
|
}
|
||||||
const { data } = (await api.getMemoList(memoFind)).data;
|
const { data } = (await api.getMemoList(memoFind)).data;
|
||||||
const archivedMemos = data.map((m) => {
|
const archivedMemos = data.map((m) => {
|
||||||
return convertResponseModelMemo(m);
|
return convertResponseModelMemo(m);
|
||||||
@ -50,9 +53,10 @@ const memoService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateTagsState: async () => {
|
updateTagsState: async () => {
|
||||||
const tagFind: TagFind = {
|
const tagFind: TagFind = {};
|
||||||
creatorId: userService.getUserIdFromPath(),
|
if (userService.isVisitorMode()) {
|
||||||
};
|
tagFind.creatorId = userService.getUserIdFromPath();
|
||||||
|
}
|
||||||
const { data } = (await api.getTagList(tagFind)).data;
|
const { data } = (await api.getTagList(tagFind)).data;
|
||||||
store.dispatch(setTags(data));
|
store.dispatch(setTags(data));
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,7 @@ import { isUndefined } from "lodash-es";
|
|||||||
import { locationService } from ".";
|
import { locationService } from ".";
|
||||||
import * as api from "../helpers/api";
|
import * as api from "../helpers/api";
|
||||||
import store from "../store";
|
import store from "../store";
|
||||||
import { setUser, patchUser } from "../store/modules/user";
|
import { setUser, patchUser, setHost, setOwner } from "../store/modules/user";
|
||||||
|
|
||||||
const convertResponseModelUser = (user: User): User => {
|
const convertResponseModelUser = (user: User): User => {
|
||||||
return {
|
return {
|
||||||
@ -17,12 +17,30 @@ const userService = {
|
|||||||
return store.getState().user;
|
return store.getState().user;
|
||||||
},
|
},
|
||||||
|
|
||||||
isVisitorMode: () => {
|
initialState: async () => {
|
||||||
return !isUndefined(userService.getUserIdFromPath());
|
const {
|
||||||
|
data: { host },
|
||||||
|
} = (await api.getSystemStatus()).data;
|
||||||
|
if (host) {
|
||||||
|
store.dispatch(setHost(convertResponseModelUser(host)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownerUserId = userService.getUserIdFromPath();
|
||||||
|
if (ownerUserId) {
|
||||||
|
const { data: owner } = (await api.getUserById(ownerUserId)).data;
|
||||||
|
if (owner) {
|
||||||
|
store.dispatch(setOwner(convertResponseModelUser(owner)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: user } = (await api.getUser()).data;
|
||||||
|
if (user) {
|
||||||
|
store.dispatch(setUser(convertResponseModelUser(user)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentUserId: () => {
|
isVisitorMode: () => {
|
||||||
return userService.getUserIdFromPath() ?? store.getState().user.user?.id;
|
return !isUndefined(userService.getUserIdFromPath());
|
||||||
},
|
},
|
||||||
|
|
||||||
getUserIdFromPath: () => {
|
getUserIdFromPath: () => {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
// host is the user who hist the system
|
||||||
|
host?: User;
|
||||||
|
// owner is the user who owns the page. If in `/u/101`, then owner's id is `101`
|
||||||
|
owner?: User;
|
||||||
|
// user is the user who is currently logged in
|
||||||
user?: User;
|
user?: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8,6 +13,18 @@ const userSlice = createSlice({
|
|||||||
name: "user",
|
name: "user",
|
||||||
initialState: {} as State,
|
initialState: {} as State,
|
||||||
reducers: {
|
reducers: {
|
||||||
|
setHost: (state, action: PayloadAction<User | undefined>) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
host: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
setOwner: (state, action: PayloadAction<User | undefined>) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
owner: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
setUser: (state, action: PayloadAction<User | undefined>) => {
|
setUser: (state, action: PayloadAction<User | undefined>) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@ -26,6 +43,6 @@ const userSlice = createSlice({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { setUser, patchUser } = userSlice.actions;
|
export const { setHost, setOwner, setUser, patchUser } = userSlice.actions;
|
||||||
|
|
||||||
export default userSlice.reducer;
|
export default userSlice.reducer;
|
||||||
|
Reference in New Issue
Block a user