mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: add contest balloon list (#578)
Co-authored-by: undefined <i@undefined.moe>
This commit is contained in:
1 parent
8e8c263477
commit
867cd069c5
15 files changed
+341
-8
No files matched your search
@@ -195,3 +195,16 @@ $highlight-button-color = #F6DF45
|
||||
.page--contest_user
|
||||
.col--uid
|
||||
width: rem(100px)
|
||||
|
||||
.page--contest_balloon
|
||||
.col--bid
|
||||
width: rem(100px)
|
||||
|
||||
.col--status
|
||||
width: rem(100px)
|
||||
|
||||
.col--problem
|
||||
width: rem(150px)
|
||||
|
||||
.col--awards
|
||||
width: rem(130px)
|
||||
@@ -0,0 +1,123 @@
|
||||
import $ from 'jquery';
|
||||
import yaml from 'js-yaml';
|
||||
import React from 'react';
|
||||
import { HexColorInput, HexColorPicker } from 'react-colorful';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { ActionDialog } from 'vj/components/dialog';
|
||||
import Notification from 'vj/components/notification';
|
||||
import { NamedPage } from 'vj/misc/Page';
|
||||
import {
|
||||
i18n, pjax, request, tpl,
|
||||
} from 'vj/utils';
|
||||
|
||||
function Balloon({ tdoc, val }) {
|
||||
const [color, setColor] = React.useState('');
|
||||
const [now, setNow] = React.useState('');
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="medium-12 columns">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{i18n('Problem')}</th>
|
||||
<th>{i18n('Color')}</th>
|
||||
<th>{i18n('Name')}</th>
|
||||
<th><span className="icon icon-wrench"></span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tdoc.pids.map((pid) => {
|
||||
const { color: c, name } = val[+pid];
|
||||
return (
|
||||
<tr key={pid}>
|
||||
<td>
|
||||
{now === pid
|
||||
? (<b>{String.fromCharCode(65 + tdoc.pids.indexOf(+pid))}</b>)
|
||||
: (<span>{String.fromCharCode(65 + tdoc.pids.indexOf(+pid))}</span>)}
|
||||
</td>
|
||||
<td>
|
||||
<HexColorInput
|
||||
className='textbox'
|
||||
color={c}
|
||||
onFocus={() => { setNow(pid); setColor(c); }}
|
||||
onChange={(e) => { val[+pid].color = e; setColor(e); }}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="textbox"
|
||||
defaultValue={name}
|
||||
onFocus={() => { setNow(pid); setColor(c); }}
|
||||
onChange={(e) => { val[+pid].name = e.target.value; }}
|
||||
/>
|
||||
</td>
|
||||
{tdoc.pids.indexOf(+pid) === 0 && <td rowSpan={0}>
|
||||
{now && <HexColorPicker color={color} onChange={(e) => { val[+now].color = e; setColor(e); }} style={{ padding: '1rem' }} />}
|
||||
</td>}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
async function handleSetColor(tdoc) {
|
||||
let val = tdoc.balloon;
|
||||
if (!val) {
|
||||
val = {};
|
||||
for (const pid of tdoc.pids) val[+pid] = { color: '#ffffff', name: '' };
|
||||
}
|
||||
Notification.info(i18n('Loading...'));
|
||||
const promise = new ActionDialog({
|
||||
$body: tpl`
|
||||
<div className="row"><div className="columns">
|
||||
<h1>${i18n('Set Color')}</h1>
|
||||
</div></div>
|
||||
<div id="balloon"></div>`,
|
||||
}).open();
|
||||
createRoot($('#balloon').get(0)).render(
|
||||
<Balloon tdoc={tdoc} val={val} />,
|
||||
);
|
||||
const action = await promise;
|
||||
if (action !== 'ok') return;
|
||||
Notification.info(i18n('Updating...'));
|
||||
try {
|
||||
await request.post('', { operation: 'set_color', color: yaml.dump(val) });
|
||||
} catch (e) {
|
||||
Notification.error(`${e.message} ${e.params?.[0]}`);
|
||||
}
|
||||
Notification.info(i18n('Successfully updated.'));
|
||||
pjax.request({ url: '', push: false });
|
||||
}
|
||||
|
||||
const page = new NamedPage('contest_balloon', () => {
|
||||
const { tdoc } = UiContext;
|
||||
|
||||
const beginAt = new Date(tdoc.beginAt).getTime();
|
||||
const endAt = new Date(tdoc.endAt).getTime();
|
||||
function update() {
|
||||
const now = Date.now();
|
||||
if (beginAt <= now && now <= endAt) pjax.request({ url: '', push: false });
|
||||
}
|
||||
|
||||
$('[name="set_color"]').on('click', () => handleSetColor(tdoc));
|
||||
setInterval(update, 60000);
|
||||
|
||||
$(document).on('click', '[value="done"]', async (ev) => {
|
||||
ev.preventDefault();
|
||||
const balloon = $(ev.currentTarget).data('balloon');
|
||||
try {
|
||||
await request.post('', { balloon, operation: 'done' });
|
||||
} catch (e) {
|
||||
Notification.error(`${e.message} ${e.params?.[0]}`);
|
||||
}
|
||||
Notification.info(i18n('Successfully updated.'));
|
||||
pjax.request({ url: '', push: false });
|
||||
});
|
||||
});
|
||||
|
||||
export default page;
|
||||
Reference in new issue
Block a user