Skip to content

Commit

Permalink
feat(api): replace prolong with extend
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Feb 8, 2024
1 parent 4644a8c commit f8535f7
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 54 deletions.
41 changes: 21 additions & 20 deletions src/GZCTF/ClientApp/src/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1739,10 +1739,9 @@ export interface SignatureVerifyModel {
publicKey: string;
}

import type {AxiosInstance, AxiosRequestConfig, AxiosResponse, HeadersDefaults, ResponseType} from "axios";
import { apiLanguage } from "@Utils/I18n";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, HeadersDefaults, ResponseType } from "axios";
import axios from "axios";
import useSWR, {mutate, MutatorOptions, SWRConfiguration} from "swr";
import {currentLanguage} from "@Utils/I18n";

export type QueryParamsType = Record<string | number, any>;

Expand Down Expand Up @@ -1863,7 +1862,7 @@ export class HttpClient<SecurityDataType = unknown> {
headers: {
...(requestParams.headers || {}),
...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}),
...({ "Accept-Language": currentLanguage.replace("_", "-") })
...{ "Accept-Language": apiLanguage },
},
params: query,
responseType: responseFormat,
Expand All @@ -1873,6 +1872,8 @@ export class HttpClient<SecurityDataType = unknown> {
};
}

import useSWR, { MutatorOptions, SWRConfiguration, mutate } from "swr";

/**
* @title GZCTF Server API
* @version v1
Expand Down Expand Up @@ -3653,6 +3654,22 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
options?: MutatorOptions,
) => mutate<GameEvent[]>([`/api/game/${id}/events`, query], data, options),

/**
* @description 延长容器时间,需要User权限,且只能在到期前十分钟延期两小时
*
* @tags Game
* @name GameExtendContainerLifetime
* @summary 延长容器时间
* @request POST:/api/game/{id}/container/{challengeId}/extend
*/
gameExtendContainerLifetime: (id: number, challengeId: number, params: RequestParams = {}) =>
this.request<ContainerInfoModel, RequestResponse>({
path: `/api/game/${id}/container/${challengeId}/extend`,
method: "POST",
format: "json",
...params,
}),

/**
* @description 获取比赛的详细信息
*
Expand Down Expand Up @@ -4124,22 +4141,6 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
options?: MutatorOptions,
) => mutate<ParticipationInfoModel[]>(`/api/game/${id}/participations`, data, options),

/**
* @description 延长容器时间,需要User权限,且只能在到期前十分钟延期两小时
*
* @tags Game
* @name GameProlongContainer
* @summary 延长容器时间
* @request POST:/api/game/{id}/container/{challengeId}/prolong
*/
gameProlongContainer: (id: number, challengeId: number, params: RequestParams = {}) =>
this.request<ContainerInfoModel, RequestResponse>({
path: `/api/game/${id}/container/${challengeId}/prolong`,
method: "POST",
format: "json",
...params,
}),

/**
* @description 获取积分榜数据
*
Expand Down
6 changes: 3 additions & 3 deletions src/GZCTF/ClientApp/src/components/ChallengeDetailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ const ChallengeDetailModal: FC<ChallengeDetailModalProps> = (props) => {
.finally(() => setDisabled(false))
}

const onProlongContainer = () => {
const onExtendContainer = () => {
if (!challengeId) return
setDisabled(true)
api.game
.gameProlongContainer(gameId, challengeId)
.gameExtendContainerLifetime(gameId, challengeId)
.then((res) => {
mutate({
...challenge,
Expand Down Expand Up @@ -331,7 +331,7 @@ const ChallengeDetailModal: FC<ChallengeDetailModalProps> = (props) => {
<InstanceEntry
context={challenge.context}
onCreate={onCreateContainer}
onProlong={onProlongContainer}
onExtend={onExtendContainer}
onDestroy={onDestroyContainer}
disabled={disabled}
/>
Expand Down
40 changes: 20 additions & 20 deletions src/GZCTF/ClientApp/src/components/InstanceEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ interface InstanceEntryProps {
context: ClientFlagContext
disabled: boolean
onCreate?: () => void
onProlong?: () => void
onExtend?: () => void
onDestroy?: () => void
}

dayjs.extend(duration)

interface CountdownProps {
time: string
prolongNotice: () => void
extendNotice: () => void
}

const Countdown: FC<CountdownProps> = ({ time, prolongNotice }) => {
const Countdown: FC<CountdownProps> = ({ time, extendNotice }) => {
const [now, setNow] = useState(dayjs())
const end = dayjs(time)
const countdown = dayjs.duration(end.diff(now))
Expand All @@ -60,7 +60,7 @@ const Countdown: FC<CountdownProps> = ({ time, prolongNotice }) => {
if (countdown.asSeconds() <= 0) return

if (countdown.asMinutes() < 10 && !haveNoticed) {
prolongNotice()
extendNotice()
setHaveNoticed(true)
} else if (countdown.asMinutes() > 10) {
setHaveNoticed(false)
Expand All @@ -83,39 +83,39 @@ export const InstanceEntry: FC<InstanceEntryProps> = (props) => {
const isPlatformProxy = instanceEntry.length === 36 && !instanceEntry.includes(':')
const copyEntry = isPlatformProxy ? getProxyUrl(instanceEntry, test) : instanceEntry

const [canProlong, setCanProlong] = useState(false)
const [canExtend, setCanExtend] = useState(false)

const { t } = useTranslation()

const prolongNotice = () => {
if (canProlong) return
const extendNotice = () => {
if (canExtend) return

showNotification({
color: 'orange',
title: t('challenge.notification.instance.prolong.note.title'),
message: t('challenge.notification.instance.prolong.note.message'),
title: t('challenge.notification.instance.extend.note.title'),
message: t('challenge.notification.instance.extend.note.message'),
icon: <Icon path={mdiExclamation} size={1} />,
})

setCanProlong(true)
setCanExtend(true)
}

useEffect(() => {
setWithContainer(!!context.instanceEntry)
const countdown = dayjs.duration(dayjs(context.closeTime ?? 0).diff(dayjs()))
setCanProlong(countdown.asMinutes() < 10)
setCanExtend(countdown.asMinutes() < 10)
}, [context])

const onProlong = () => {
if (!canProlong || !props.onProlong) return
const onExtend = () => {
if (!canExtend || !props.onExtend) return

props.onProlong()
setCanProlong(false)
props.onExtend()
setCanExtend(false)

showNotification({
color: 'teal',
title: t('challenge.notification.instance.prolong.success.title'),
message: t('challenge.notification.instance.prolong.success.message'),
title: t('challenge.notification.instance.extend.success.title'),
message: t('challenge.notification.instance.extend.success.message'),
icon: <Icon path={mdiCheck} size={1} />,
})
}
Expand Down Expand Up @@ -225,16 +225,16 @@ export const InstanceEntry: FC<InstanceEntryProps> = (props) => {
<Stack align="left" spacing={0}>
<Text size="sm" fw={600}>
{t('challenge.content.instance.actions.count_down')}
<Countdown time={context.closeTime ?? '0'} prolongNotice={prolongNotice} />
<Countdown time={context.closeTime ?? '0'} extendNotice={extendNotice} />
</Text>
<Text size="xs" color="dimmed" fw={600}>
{t('challenge.content.instance.actions.note')}
</Text>
</Stack>

<Group position="right" noWrap spacing="xs">
<Button color="orange" onClick={onProlong} disabled={!canProlong}>
{t('challenge.button.instance.prolong')}
<Button color="orange" onClick={onExtend} disabled={!canExtend}>
{t('challenge.button.instance.extend')}
</Button>
<Button color="red" onClick={onDestroy} disabled={disabled}>
{t('challenge.button.instance.destroy')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const ChallengePreviewModal: FC<ChallengePreviewModalProps> = (props) => {
context={context}
disabled={false}
onCreate={onCreate}
onProlong={onCreate}
onExtend={onCreate}
onDestroy={onDestroy}
/>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/GZCTF/ClientApp/src/locales/en_US/challenge.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"submit_flag": "Submit Flag",
"instance": {
"create": "Create",
"prolong": "Extend",
"extend": "Extend",
"destroy": "Destroy"
}
},
Expand Down Expand Up @@ -105,7 +105,7 @@
"title": "Instance entry copied to clipboard"
}
},
"prolong": {
"extend": {
"note": {
"message": "Please extend lifetime or destroy instance in time",
"title": "Instance is due"
Expand Down
4 changes: 2 additions & 2 deletions src/GZCTF/ClientApp/src/locales/ja_JP/challenge.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"submit_flag": "フラッグを提出",
"instance": {
"create": "インスタンスを作成",
"prolong": "期限を延ばす",
"extend": "期限を延ばす",
"destroy": "インスタンスを破棄"
}
},
Expand Down Expand Up @@ -105,7 +105,7 @@
"title": "インスタンスのエントリーがコピーされました"
}
},
"prolong": {
"extend": {
"note": {
"message": "期限を延長するか、期限内にインスタンスを破棄してください",
"title": "インスタンスの有効期限が近づいています"
Expand Down
4 changes: 2 additions & 2 deletions src/GZCTF/ClientApp/src/locales/zh_CN/challenge.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"submit_flag": "提交 flag",
"instance": {
"create": "创建实例",
"prolong": "延长时间",
"extend": "延长时间",
"destroy": "销毁实例"
}
},
Expand Down Expand Up @@ -105,7 +105,7 @@
"title": "实例入口已复制到剪贴板"
}
},
"prolong": {
"extend": {
"note": {
"message": "请及时延长时间或销毁实例",
"title": "实例即将到期"
Expand Down
4 changes: 2 additions & 2 deletions src/GZCTF/ClientApp/src/utils/I18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const useLanguage = () => {

useEffect(() => {
i18n.changeLanguage(language)
currentLanguage = language
apiLanguage = language.replace("_", "-")
}, [language])

const supportedLanguages = Object.keys(resources) as SupportedLanguages[]
Expand All @@ -40,4 +40,4 @@ export const useLanguage = () => {
return { language, setLanguage, supportedLanguages }
}

export let currentLanguage: string = 'zh-CN';
export let apiLanguage: string = 'zh-CN'
4 changes: 2 additions & 2 deletions src/GZCTF/ClientApp/template/http-client.eta
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { apiConfig, generateResponses, config } = it;

import type { AxiosInstance, AxiosRequestConfig, HeadersDefaults, ResponseType, AxiosResponse } from "axios";
import axios from "axios";
import { currentLanguage } from "@Utils/I18n";
import { apiLanguage } from "@Utils/I18n";

export type QueryParamsType = Record<string | number, any>;

Expand Down Expand Up @@ -126,7 +126,7 @@ export class HttpClient<SecurityDataType = unknown> {
headers: {
...(requestParams.headers || {}),
...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}),
...({ "Accept-Language": currentLanguage.replace("_", "-") })
...{ "Accept-Language": apiLanguage }
},
params: query,
responseType: responseFormat,
Expand Down

0 comments on commit f8535f7

Please sign in to comment.