Spaces:
Sleeping
Sleeping
fix: clear template on keydown via JS + CodeMirror cmView API, drop broken Python handler
Browse files
app.py
CHANGED
|
@@ -369,6 +369,7 @@ def build_app() -> gr.Blocks:
|
|
| 369 |
language="python",
|
| 370 |
lines=20,
|
| 371 |
value="# Write your solution here using Legesher\n# Use native-language variable and function names\n",
|
|
|
|
| 372 |
)
|
| 373 |
|
| 374 |
with gr.Row():
|
|
@@ -414,33 +415,9 @@ def build_app() -> gr.Blocks:
|
|
| 414 |
# ---- State ----
|
| 415 |
tier_idx_state = gr.State(value=0)
|
| 416 |
lang_state = gr.State(value="zh")
|
| 417 |
-
template_cleared = gr.State(value=False)
|
| 418 |
|
| 419 |
# ---- Event wiring ----
|
| 420 |
|
| 421 |
-
_T1 = "# Write your solution here using Legesher"
|
| 422 |
-
_T2 = "# Use native-language variable and function names"
|
| 423 |
-
_TEMPLATE = f"{_T1}\n{_T2}\n"
|
| 424 |
-
|
| 425 |
-
def on_code_change(code: str, cleared: bool):
|
| 426 |
-
"""On the user's first real edit, strip the template strings then never run again."""
|
| 427 |
-
if cleared:
|
| 428 |
-
return gr.update(), True
|
| 429 |
-
# Nothing typed yet — template still untouched
|
| 430 |
-
if code.strip() in ("", _T1, _T2, f"{_T1}\n{_T2}"):
|
| 431 |
-
return gr.update(), False
|
| 432 |
-
# Strip the two template lines wherever they appear via substring replace
|
| 433 |
-
cleaned = code.replace(_T1 + "\n", "").replace(_T2 + "\n", "")
|
| 434 |
-
cleaned = cleaned.replace(_T1, "").replace(_T2, "")
|
| 435 |
-
cleaned = cleaned.lstrip("\n")
|
| 436 |
-
return cleaned, True
|
| 437 |
-
|
| 438 |
-
code_editor.change(
|
| 439 |
-
fn=on_code_change,
|
| 440 |
-
inputs=[code_editor, template_cleared],
|
| 441 |
-
outputs=[code_editor, template_cleared],
|
| 442 |
-
)
|
| 443 |
-
|
| 444 |
def tier_to_idx(tier_label: str) -> int:
|
| 445 |
return TIER_LABELS.index(tier_label)
|
| 446 |
|
|
@@ -504,8 +481,8 @@ def build_app() -> gr.Blocks:
|
|
| 504 |
)
|
| 505 |
|
| 506 |
clear_btn.click(
|
| 507 |
-
fn=lambda: ("# Write your solution here using Legesher\n# Use native-language variable and function names\n", "", ""
|
| 508 |
-
outputs=[code_editor, stdin_input, run_output
|
| 509 |
)
|
| 510 |
|
| 511 |
submit_btn.click(
|
|
@@ -521,6 +498,36 @@ def build_app() -> gr.Blocks:
|
|
| 521 |
outputs=[submit_status],
|
| 522 |
)
|
| 523 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
return app
|
| 525 |
|
| 526 |
|
|
|
|
| 369 |
language="python",
|
| 370 |
lines=20,
|
| 371 |
value="# Write your solution here using Legesher\n# Use native-language variable and function names\n",
|
| 372 |
+
elem_id="legesher-code-editor",
|
| 373 |
)
|
| 374 |
|
| 375 |
with gr.Row():
|
|
|
|
| 415 |
# ---- State ----
|
| 416 |
tier_idx_state = gr.State(value=0)
|
| 417 |
lang_state = gr.State(value="zh")
|
|
|
|
| 418 |
|
| 419 |
# ---- Event wiring ----
|
| 420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 421 |
def tier_to_idx(tier_label: str) -> int:
|
| 422 |
return TIER_LABELS.index(tier_label)
|
| 423 |
|
|
|
|
| 481 |
)
|
| 482 |
|
| 483 |
clear_btn.click(
|
| 484 |
+
fn=lambda: ("# Write your solution here using Legesher\n# Use native-language variable and function names\n", "", ""),
|
| 485 |
+
outputs=[code_editor, stdin_input, run_output],
|
| 486 |
)
|
| 487 |
|
| 488 |
submit_btn.click(
|
|
|
|
| 498 |
outputs=[submit_status],
|
| 499 |
)
|
| 500 |
|
| 501 |
+
# ---- JS: clear template on first keystroke (client-side, no server round-trip) ----
|
| 502 |
+
_CLEAR_TEMPLATE_JS = """
|
| 503 |
+
function() {
|
| 504 |
+
const T1 = '# Write your solution here using Legesher';
|
| 505 |
+
const T2 = '# Use native-language variable and function names';
|
| 506 |
+
|
| 507 |
+
function clearTemplate(view) {
|
| 508 |
+
const doc = view.state.doc.toString();
|
| 509 |
+
if (!doc.includes(T1) && !doc.includes(T2)) return;
|
| 510 |
+
let cleaned = doc
|
| 511 |
+
.replace(T1 + '\\n', '').replace(T2 + '\\n', '')
|
| 512 |
+
.replace(T1, '').replace(T2, '');
|
| 513 |
+
cleaned = cleaned.replace(/^\\n+/, '');
|
| 514 |
+
view.dispatch({
|
| 515 |
+
changes: { from: 0, to: view.state.doc.length, insert: cleaned },
|
| 516 |
+
selection: { anchor: 0 }
|
| 517 |
+
});
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
function setup() {
|
| 521 |
+
const wrap = document.querySelector('#legesher-code-editor .cm-editor');
|
| 522 |
+
if (!wrap || !wrap.cmView) { setTimeout(setup, 300); return; }
|
| 523 |
+
wrap.addEventListener('keydown', () => clearTemplate(wrap.cmView), true);
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
setTimeout(setup, 600);
|
| 527 |
+
}
|
| 528 |
+
"""
|
| 529 |
+
app.load(fn=None, js=_CLEAR_TEMPLATE_JS)
|
| 530 |
+
|
| 531 |
return app
|
| 532 |
|
| 533 |
|