import yaml from 'js-yaml';
import ReactDOM, { createRoot } from 'react-dom/client';
import React from 'react';
import { getScoreColor } from '@hydrooj/utils/lib/status';
import { NamedPage } from 'vj/misc/Page';
import { downloadProblemSet } from 'vj/components/zipDownloader';
import loadReactRedux from 'vj/utils/loadReactRedux';
import delay from 'vj/utils/delay';
import pjax from 'vj/utils/pjax';
class ProblemPageExtender {
constructor() {
this.isExtended = false;
this.inProgress = false;
this.$content = $('.problem-content-container');
this.$contentBound = this.$content.closest('.section');
this.$scratchpadContainer = $('.scratchpad-container');
}
async extend() {
if (this.inProgress) return;
if (this.isExtended) return;
this.inProgress = true;
const bound = this.$contentBound
.get(0)
.getBoundingClientRect();
this.$content.transition({ opacity: 0 }, { duration: 100 });
await delay(100);
$('body').addClass('header--collapsed mode--scratchpad');
await this.$scratchpadContainer
.css({
left: bound.left,
top: bound.top,
width: bound.width,
height: bound.height,
})
.show()
.transition({
left: 0,
top: 0,
width: '100%',
height: '100%',
}, {
duration: 500,
easing: 'easeOutCubic',
})
.promise();
$('.main > .row').hide();
$('.footer').hide();
$(window).scrollTop(0);
window.document.body.style.overflow = 'hidden';
this.inProgress = false;
this.isExtended = true;
}
async collapse() {
if (this.inProgress) return;
if (!this.isExtended) return;
this.inProgress = true;
$(window).scrollTop(0);
$('.main > .row').show();
$('.footer').show();
const bound = this.$contentBound
.get(0)
.getBoundingClientRect();
$('body').removeClass('header--collapsed mode--scratchpad');
await this.$scratchpadContainer
.transition({
left: bound.left,
top: bound.top,
width: bound.width,
height: bound.height,
}, {
duration: 500,
easing: 'easeOutCubic',
})
.promise();
this.$scratchpadContainer.hide();
this.$content.transition({ opacity: 1 }, { duration: 100 });
window.document.body.style.overflow = 'scroll';
this.inProgress = false;
this.isExtended = false;
}
toggle() {
if (this.isExtended) this.collapse();
else this.extend();
}
}
const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homework_detail_problem'], async (pagename) => {
let reactLoaded = false;
let renderReact = null;
let unmountReact = null;
const extender = new ProblemPageExtender();
async function handleClickDownloadProblem() {
await downloadProblemSet([UiContext.problemNumId], UiContext.pdoc.title);
}
async function scratchpadFadeIn() {
await $('#scratchpad')
.transition(
{ opacity: 1 },
{ duration: 200, easing: 'easeOutCubic' },
)
.promise();
}
async function scratchpadFadeOut() {
await $('#scratchpad')
.transition(
{ opacity: 0 },
{ duration: 200, easing: 'easeOutCubic' },
)
.promise();
}
async function loadReact() {
if (reactLoaded) return;
$('.loader-container').show();
const { default: WebSocket } = await import('../components/socket');
const { default: ScratchpadApp } = await import('../components/scratchpad');
const { default: ScratchpadReducer } = await import('../components/scratchpad/reducers');
const { Provider, store } = await loadReactRedux(ScratchpadReducer);
const sock = new WebSocket(UiContext.pretestConnUrl);
sock.onmessage = (message) => {
const msg = JSON.parse(message.data);
store.dispatch({
type: 'SCRATCHPAD_RECORDS_PUSH',
payload: msg,
});
};
const root = createRoot($('#scratchpad').get(0));
renderReact = () => {
root.render(