|
262 | 262 |
|
263 | 263 | <!-- Right/Bottom Challenge Area--> |
264 | 264 | <div class="challenge-area"> |
265 | | - <!-- Challenge Header Area--> |
266 | | - <div class="challenge-header"> |
267 | | - <div class="challenge-header__title"> |
268 | | - <span>Challenge - {{ name }}</span> |
269 | | - {%include 'components/badge.html' with context %} |
270 | | - </div> |
271 | | - <p class="challenge-header__exerpt"> |
272 | | - Complete code following the instructions, so that lines followed by |
273 | | - <code># expect-type-error</code> (if any) |
274 | | - fail type check, while others can pass.<br> |
275 | | - Hit the "▶️ Run" button to see result. |
276 | | - </p> |
277 | | - <div class="hints-container"> |
278 | | - {% if hints_for_display %} |
279 | | - <a id="read-hints" role="button" class="secondary outline" href="javascript:void(0);">💡 Read Hints</a> |
280 | | - {% else %} |
281 | | - <div id="hints-missing">💡 No Hints Available</div> |
282 | | - {% endif %} |
283 | | - <article class="hints-message">{{hints_for_display | safe}}</article> |
284 | | - </div> |
285 | | - </div> |
286 | | - |
287 | | - <div class="challenge-main"> |
288 | | - <!-- Code Editor Area --> |
289 | | - <div class="codemirror-container"> |
290 | | - <div id="editor"> |
291 | | - <a id="playground-link" target="_blank" rel="noopener noreferrer"> |
292 | | - <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4m-8-2l8-8m0 0v5m0-5h-5"/></svg> |
293 | | - <span>Open Pyright Playground</span> |
294 | | - </a> |
295 | | - </div> |
296 | | - <div class="editor-actions"> |
297 | | - <p id="answer-link">Stuck? Check out |
298 | | - <a target="_blank" rel="noopener noreferrer" |
299 | | - href="https://github.com/laike9m/Python-Type-Challenges/tree/main/challenges/{{level}}-{{name}}/solution.py"> |
300 | | - solution |
301 | | - </a> |
302 | | - </p> |
303 | | - <button id="reset-button" class="secondary"> |
304 | | - Reset |
305 | | - </button> |
306 | | - <button id="run-button"> |
307 | | - ▶️ Run |
308 | | - </button> |
309 | | - </div> |
310 | | - </div> |
311 | | - <!-- Test Cases and Result Area --> |
312 | | - <div class="tests-result-container"> |
313 | | - <div id="tests"></div> |
314 | | - <div id="result"></div> |
315 | | - </div> |
316 | | - </div> |
| 265 | + {% include "components/challenge_area.html" %} |
317 | 266 | </div> |
318 | 267 | </div> |
319 | | - |
320 | | - <script type="text/javascript"> |
321 | | - let confetti = new JSConfetti(); |
322 | | - let initTheme = localStorage.getItem('theme') === 'dark' ? "material-darker" : "default" |
323 | | - let sharedCodeMirrorOptions = { |
324 | | - mode: "python", |
325 | | - lineWrapping: true, |
326 | | - lineNumbers: true, |
327 | | - indentUnit: 4, |
328 | | - theme: initTheme, |
329 | | - } |
330 | | - let code_under_test = {{ code_under_test | tojson }}; |
331 | | - let myCodeMirror = CodeMirror(document.getElementById("editor"), { |
332 | | - value: code_under_test, |
333 | | - ...sharedCodeMirrorOptions, |
334 | | - }); |
335 | | - let test_code = {{ test_code | tojson }}; |
336 | | - let testCodeMirror = CodeMirror(document.getElementById("tests"), { |
337 | | - value: test_code, |
338 | | - readOnly: "nocursor", |
339 | | - ...sharedCodeMirrorOptions, |
340 | | - }); |
341 | | - |
342 | | - let playgroundLink = document.getElementById("playground-link"); |
343 | | - playgroundLink.addEventListener('click', function (event) { |
344 | | - const code = myCodeMirror.getValue() + testCodeMirror.getValue(); |
345 | | - this.href = "https://pyright-play.net/?code=" + LZString.compressToEncodedURIComponent(code); |
346 | | - }); |
347 | | - |
348 | | - window.addEventListener('themeSwitch', function (event) { |
349 | | - let theme = localStorage.getItem('theme') === 'dark' ? "material-darker" : "default" |
350 | | - myCodeMirror.setOption("theme", theme); |
351 | | - testCodeMirror.setOption("theme", theme); |
352 | | - }) |
353 | | - |
354 | | - let runButton = document.getElementById('run-button') |
355 | | - runButton.onclick = function () { |
356 | | - console.log(`Run challenge at: ${new Date().toLocaleString()}`); |
357 | | - |
358 | | - // set button spinner |
359 | | - let rawInnerText = runButton.innerText; |
360 | | - runButton.ariaBusy = true; |
361 | | - runButton.innerText = "" |
362 | | - |
363 | | - let code = myCodeMirror.getValue(); |
364 | | - fetch('/run/{{level}}/{{name}}', { |
365 | | - method: 'POST', |
366 | | - body: code |
367 | | - }) |
368 | | - .then(response => response.json()) |
369 | | - .then(json => { |
370 | | - // add confetti effect when passed |
371 | | - if (json.passed) { |
372 | | - confetti.addConfetti() |
373 | | - } |
374 | | - setTimeout(() => { |
375 | | - document.getElementById('answer-link').style.display = 'block'; |
376 | | - }, 500); |
377 | | - document.getElementById("result").innerHTML = json.message; |
378 | | - if (json.debug_info !== undefined) { |
379 | | - console.log(json.debug_info); |
380 | | - } |
381 | | - }) |
382 | | - .catch((error) => { |
383 | | - console.error('Error:', error); |
384 | | - }) |
385 | | - .finally(() => { |
386 | | - // reset button spinner |
387 | | - runButton.ariaBusy = false; |
388 | | - runButton.innerText = rawInnerText; |
389 | | - }); |
390 | | - }; |
391 | | - |
392 | | - let resetButton = document.getElementById('reset-button') |
393 | | - resetButton.onclick = function () { |
394 | | - myCodeMirror.setValue(code_under_test); |
395 | | - }; |
396 | | - |
397 | | - // Set up hints events and functions |
398 | | - let hintBtn = document.getElementById('read-hints') |
399 | | - hintBtn.onclick = function () { |
400 | | - // Toggle the display of the hints message. |
401 | | - let msgElem = document.getElementsByClassName('hints-message')[0]; |
402 | | - if (msgElem.style.display === 'block') { |
403 | | - msgElem.style.display = 'none'; |
404 | | - } else { |
405 | | - msgElem.style.display = 'block'; |
406 | | - } |
407 | | - }; |
408 | | - // Make sure to open links in hints in new tab. |
409 | | - document.querySelectorAll('.hints-message a').forEach(function(elem) { |
410 | | - elem.setAttribute('target', '_blank'); |
411 | | - }) |
412 | | - |
413 | | - // Make sure the current challenge is visible to user. |
414 | | - activeChallengeInList = document.getElementById("{{level}}-{{name}}"); |
415 | | - activeChallengeInList.scrollIntoView({block: 'center'}); |
416 | | - activeChallengeInList.classList.add('active-challenge'); // Highlight |
417 | | - </script> |
418 | 268 | {% endblock %} |
0 commit comments