Skip to content

Commit

Permalink
Perf user experience
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Sep 30, 2024
1 parent 91fac5c commit 732d95f
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/apis/judge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function postJudge(slug: string, code: string, language: string) {
};
let data = JSON.stringify(body);

let res = await axiosClient.post<JudgeServiceModel.JudgeVerdict[]>(
let res = await axiosClient.post<JudgeServiceModel.JudgeInfo>(
`/api/v1/problem/${slug}/judge`,
data,
);
Expand Down
5 changes: 4 additions & 1 deletion src/components/display/MarkdownRender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism";
import rehypeReact from "rehype-react";
import { joinClasses } from "@/utils/common";
import rehypeRaw from "rehype-raw";
import { useTranslation } from "react-i18next";

interface MarkdownRenderProps {
content: string;
Expand Down Expand Up @@ -53,6 +54,8 @@ interface CodeBlockProps {
}

const CodeBlock: React.FC<CodeBlockProps> = (props) => {
const { t } = useTranslation();

const handleCopy = () => {
copy(props.value);
};
Expand All @@ -63,7 +66,7 @@ const CodeBlock: React.FC<CodeBlockProps> = (props) => {
onClick={handleCopy}
className="btn btn-xs absolute right-0 top-[-1.25px] rounded"
>
Copy
{t("Copy")}
</button>
{props.language === "text" ? (
<code>{props.value}</code>
Expand Down
16 changes: 5 additions & 11 deletions src/hooks/judge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,24 @@ export const useJudge = (uid: string) => {
export const useRunJudge = (slug: string) => {
const [src, setSrc] = useState<string>("");
const [src_language, setSrcLanguage] = useState<string>("");
const [verdicts, setVerdicts] = useState<JudgeServiceModel.JudgeVerdict[]>(
[],
);

function runJudge(postJudge: () => void) {
function runJudge(
afterJudgePosted: (judgeInfo: JudgeServiceModel.JudgeInfo) => void,
) {
JudgeService.postJudge(slug, src, src_language)
.then((res) => {
setVerdicts(res);
postJudge();
afterJudgePosted(res);
})
.catch((err) => {
console.log(err);
});
}

function getVerdicts() {
return verdicts;
}

function getSrcLanguage() {
return src_language;
}

return { runJudge, getVerdicts, setSrc, setSrcLanguage, getSrcLanguage };
return { runJudge, setSrc, setSrcLanguage, getSrcLanguage };
};

export const useJudgeList = () => {
Expand Down
6 changes: 6 additions & 0 deletions src/i18n/resources/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const ZH_CN_TRANSLATIONS: Resource = {
Search: "搜索",
Login: "登录",
Logout: "登出",
Submit: "提交",
Copy: "复制",

"or Register": "或注册",
"Welcome!": "欢迎!",
"input title": "输入标题",
Expand All @@ -26,7 +29,10 @@ const ZH_CN_TRANSLATIONS: Resource = {
"Submit Time": "提交时间",
"Accept Count": "通过数",
"Accept Rate": "通过率",
"Your solution": "你的解答",
"Just look at yourself": "只看自己",
"Click and confirm submission": "点击并确认提交",
"Please login first": "请先登录",

Theme: "主题",

Expand Down
16 changes: 1 addition & 15 deletions src/layouts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import PageBreadcrumbs from "@/components/navigation/PageBreadcrumbs";
import { useEffect } from "react";
import { getCurrentUserAction } from "@/store/sagas/user";
import { useDispatch, useSelector } from "react-redux";
import {
AddMessageSagaPattern,
RemoveMessageSagaPattern,
} from "@/store/sagas/message";
import { RemoveMessageSagaPattern } from "@/store/sagas/message";
import { messageMapSelector } from "@/store/selectors";
import { joinClasses } from "@/utils/common";
import { useTranslation } from "react-i18next";
Expand All @@ -23,17 +20,6 @@ const Layout: React.FC<LayoutProps> = (props) => {
let dispatch = useDispatch();
let messageMap = useSelector(messageMapSelector);

useEffect(() => {
dispatch({
type: AddMessageSagaPattern,
payload: {
id: "welcome",
content: "🥰 Welcome to OJ Lab!",
duration: 3000,
},
});
}, [dispatch]);

useEffect(() => {
dispatch(getCurrentUserAction);
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
61 changes: 38 additions & 23 deletions src/pages/problem/Problem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import MarkdownRender from "@/components/display/MarkdownRender";
import { useProblem } from "@/hooks/problem";
import { useRunJudge } from "@/hooks/judge";
import { isGhPages, isMock } from "@/utils/environment";
import { useDispatch, useSelector } from "react-redux";
import { AddMessageSagaPattern } from "@/store/sagas/message";
import { userInfoSelector } from "@/store/selectors";
import { joinClasses } from "@/utils/common";
import { t } from "i18next";

const mockDefaultCode = `#include <iostream>
using namespace std;
Expand All @@ -19,8 +24,9 @@ int main() {

const Problem: React.FC = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const userInfo = useSelector(userInfoSelector);
const slug = useParams().slug as string;
const [toggleToast, setToggleToast] = React.useState<boolean>(false);
const codeEditorContainer = React.useRef<HTMLDivElement | null>(null);

const { getProblem } = useProblem(slug, () => {
Expand All @@ -35,22 +41,13 @@ const Problem: React.FC = () => {

return (
<div className="flex flex-col gap-4">
{toggleToast && (
<div className="toast toast-center toast-top z-10">
<div className="alert alert-success">
<span>Judge sent successfully.</span>
</div>
</div>
)}

<div className="h-fit rounded border border-base-content/10 bg-base-100 p-6">
<h1 className="mb-8 text-center text-4xl font-bold">
{getProblem()?.title}
</h1>
<MarkdownRender content={getProblem()?.description || ""} />
</div>

<p className="text-lg font-bold">Your Solution</p>
<p className="text-lg font-bold">{t("Your solution")}</p>
<select
className="select select-bordered select-sm w-fit rounded"
onChange={(e) => {
Expand All @@ -75,19 +72,37 @@ const Problem: React.FC = () => {
/>
</div>
<div className="relative">
<button
className="btn btn-primary absolute bottom-8 right-4 self-end"
onClick={() => {
runJudge(() => {
setToggleToast(true);
setTimeout(() => {
setToggleToast(false);
}, 3000);
});
}}
<div
className="tooltip tooltip-left absolute bottom-8 right-4 self-end"
data-tip={
userInfo
? t("Click and confirm submission")
: t("Please login first")
}
>
Submit
</button>
<button
className={joinClasses(
"btn btn-primary btn-sm rounded",
userInfo ? "" : "btn-disabled",
)}
onClick={() => {
runJudge((judgeInfo) => {
dispatch({
type: AddMessageSagaPattern,
payload: {
id: `judge-submitted-${judgeInfo.UID}`,
content:
t("Judge") + " " + judgeInfo.UID + " " + t("submitted"),
duration: 3000,
level: "success",
},
});
});
}}
>
{t("Submit")}
</button>
</div>
</div>
</div>
);
Expand Down
12 changes: 1 addition & 11 deletions src/store/sagas/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,13 @@ import { getCurrentUser } from "@/apis/auth";
import * as UserServiceModel from "@/models/service/user";
import { setUserInfo } from "../slices/user";
import { Action } from "redux";
import { AddMessageSagaPattern } from "./message";

function* getCurrentUserSaga() {
try {
const user: UserServiceModel.UserInfo = yield call(getCurrentUser);
yield put(setUserInfo(user));
} catch (err) {
yield put({
type: AddMessageSagaPattern,
payload: {
id: "get-current-user-error",
content: "UnAuthorized. Please login first.",
duration: 3000,
level: "error",
err: err?.toString(),
},
});
console.error(err);
}
}

Expand Down

0 comments on commit 732d95f

Please sign in to comment.