Skip to content

Commit 1336d96

Browse files
committed
feat: add share button
1 parent 2c48ea3 commit 1336d96

File tree

5 files changed

+58
-14
lines changed

5 files changed

+58
-14
lines changed

config/i18n.json

+16
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,21 @@
5858
"no_question": {
5959
"en": "No Result",
6060
"zh-CN": "暂无数据"
61+
},
62+
"compilation_error": {
63+
"en": "Compilation Error",
64+
"zh-CN": "编译失败"
65+
},
66+
"compilation_success": {
67+
"en": "Compilation Successful",
68+
"zh-CN": "编译成功"
69+
},
70+
"compilation_success_info": {
71+
"en": "\uD83C\uDF89 Yay! You have finished this challenge.",
72+
"zh-CN": "\uD83C\uDF89 恭喜你完成了这个挑战!"
73+
},
74+
"share_solution": {
75+
"en": "Share your Solution",
76+
"zh-CN": "分享你的解答"
6177
}
6278
}

src/modules/Question/Solution.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const Solution = function () {
2828

2929
return (
3030
<div className={styles['solution-container']}>
31-
<Skeleton loading={loading} style={{ marginTop: 20 }}>
31+
<Skeleton loading={loading} style={{ marginTop: 20 }} animation={true}>
3232
<Markdown content={solution} theme={theme} />
3333
</Skeleton>
3434
</div>

src/modules/Results/index.module.less

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
border-radius: 8px;
3232
font-size: 16px;
3333
}
34+
.result-accept-btns {
35+
margin-top: 24px;
36+
}
3437
}
3538
.result-accept {
3639
.result-accept-title {

src/modules/Results/index.tsx

+26-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import type { editor } from 'monaco-editor';
22
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
3-
import { Skeleton } from '@arco-design/web-react';
3+
import { Button, Skeleton } from '@arco-design/web-react';
44
import localCache, { QUESTION_STATUS } from '@src/utils/local-cache';
55
import emitter from '@src/utils/emit';
66
import Context from '@src/utils/context';
77
import { monacoEditorLoaded, monacoInstance } from '@src/utils/monaco';
88
import { QuestionFiles } from '@src/utils/type-challenges';
99
import SubmitStatus from '@src/components/SubmitStatus';
10+
import i18n from '@config/i18n.json';
11+
import { Setting } from '@src/utils/setting';
1012
import styles from './index.module.less';
1113

1214
function formatErrorFromMarkers(markers: editor.IMarker[]) {
@@ -17,12 +19,12 @@ function formatErrorFromMarkers(markers: editor.IMarker[]) {
1719
});
1820
}
1921

20-
function createResultError(status: string[]) {
22+
function createResultError(status: string[], language: Setting['language']) {
2123
return (
2224
<div className={styles['result-errors']}>
2325
<div className={styles['result-error-title']}>
2426
<SubmitStatus status={QUESTION_STATUS.unAccepted} />
25-
<span style={{ marginLeft: 8 }}>Compilation Error</span>
27+
<span style={{ marginLeft: 8 }}>{i18n['compilation_error'][language]}</span>
2628
</div>
2729
<div className={styles['result-error-info']}>
2830
{status.map(function (error) {
@@ -38,29 +40,45 @@ function createResultError(status: string[]) {
3840
}
3941

4042
const Results = function () {
41-
const [{ currentQuestion }] = useContext(Context);
43+
const [{ currentQuestion, setting: { language } }] = useContext(Context);
4244
const [loading, setLoading] = useState(true);
4345
const [status, setStatus] = useState<string[]>([]);
4446

47+
const shareSolutionHref = useMemo(function () {
48+
const questionNum = currentQuestion.match(/[0-9]+(?=-)/)?.[0];
49+
return `https://tsch.js.org/${Number(questionNum)}/answer/${language === 'en' ? '' : language}`;
50+
}, [currentQuestion, language]);
51+
4552
const resultContent = useMemo(
4653
function () {
4754
if (status.length === 0) {
4855
return (
4956
<div className={styles['result-accept']}>
5057
<div className={styles['result-accept-title']}>
5158
<SubmitStatus status={QUESTION_STATUS.accepted} />
52-
<span style={{ marginLeft: 8 }}>Compilation Successful</span>
59+
<span style={{ marginLeft: 8 }}>{i18n['compilation_success'][language]}</span>
5360
</div>
5461
<div className={styles['result-accept-info']}>
55-
🎉 Yay! You have finished this challenge.
62+
{i18n['compilation_success_info'][language]}
63+
</div>
64+
<div className={styles['result-accept-btns']}>
65+
<Button
66+
type={'primary'}
67+
status={'success'}
68+
target={'_blank'}
69+
href={shareSolutionHref}
70+
style={{ borderRadius: 4 }}
71+
>
72+
{i18n['share_solution'][language]}
73+
</Button>
5674
</div>
5775
</div>
5876
);
5977
} else {
60-
return createResultError(status);
78+
return createResultError(status, language);
6179
}
6280
},
63-
[status],
81+
[status, language],
6482
);
6583

6684
const validate = useCallback(

src/utils/type-challenges.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -131,32 +131,39 @@ class TypeChallenges {
131131
}
132132
return this.info || {};
133133
}
134-
async getSolution(cnt: number = 0): Promise<string> {
134+
async getSolution(cnt: number = 3): Promise<string> {
135135
if (this.solution) {
136136
return this.solution;
137137
}
138-
if (cnt === 3) {
138+
if (cnt === 0) {
139139
return 'Get solution failed!';
140140
}
141-
cnt += 1;
142141
const id = this.id;
143142
const index = id.match(/[0-9]+(?=-)/)?.[0];
144143
if (!index) {
145144
return 'Get solution failed!';
146145
}
146+
const controller = new AbortController();
147147
const res = await fetch(
148148
// eslint-disable-next-line max-len
149149
'https://api.github.com/repos/type-challenges/type-challenges/issues?&sort=reactions-+1-desc&per_page=1&labels=answer,' +
150-
String(Number(index)),
150+
String(Number(index)),{
151+
headers: {
152+
Accept: 'application/vnd.github+json',
153+
'X-GitHub-Api-Version': '2022-11-28'
154+
},
155+
signal: controller.signal,
156+
}
151157
);
158+
setTimeout(() => controller.abort(), 5000);
152159
try {
153160
const solutions = await res.json();
154161
const solution = solutions?.[0];
155162
const { body, html_url } = solution;
156163
this.solution = `<a href='${html_url}' target='_blank'>${html_url}</a>\n${body}`;
157164
return this.solution;
158165
} catch {
159-
return await this.getSolution(cnt);
166+
return await this.getSolution(cnt - 1);
160167
}
161168
}
162169
}

0 commit comments

Comments
 (0)