chore: update user store

pull/120/head
boojack 3 years ago
parent 10d710cf03
commit 5fd3cfdb61

@ -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;

Loading…
Cancel
Save