diff --git a/assets/exam-simulator.js b/assets/exam-simulator.js index 945d732..4fdaec3 100644 --- a/assets/exam-simulator.js +++ b/assets/exam-simulator.js @@ -508,6 +508,12 @@ function showSummary() { reviewPartIndex.value = null; view.value = "summary"; + if (completedResultUrl.value) { + var target = new URL(completedResultUrl.value); + if (window.location.pathname !== target.pathname || window.location.search !== target.search) { + window.location.assign(target.toString()); + } + } window.scrollTo({ top: 0, behavior: "smooth" }); } @@ -548,6 +554,9 @@ var questionIds = session.value && session.value.homeworkIds; if (!questionIds) return; clearStoredSession(); + var homeworkUrl = new URL("simulation.html", window.location.href); + homeworkUrl.search = "?homework=" + questionIds.join("+"); + window.history.replaceState(null, "", homeworkUrl.toString()); startHomework(questionIds); window.scrollTo({ top: 0, behavior: "smooth" }); } @@ -598,9 +607,18 @@ return "1." + result.choice.id + "." + result.scores.join("."); } - var resultForSharing = computed(function () { - if (sharedResult.value) return sharedResult.value; - if (!session.value || view.value !== "summary") return null; + function resultImageCode(result) { + if (!result) return ""; + if (result.kind === "homework") return result.score === result.total ? "aenbv" : ""; + if (!result.passed) return ""; + var order = ["A", "E", "N", "B", "V"]; + return order.filter(function (part) { + return result.choice.parts.indexOf(part) !== -1; + }).join("").toLowerCase(); + } + + function shareableSessionResult() { + if (!session.value) return null; if (isHomework.value) { return { kind: "homework", score: session.value.parts[0].score, total: session.value.parts[0].questions.length }; } @@ -611,13 +629,33 @@ scores: session.value.parts.map(function (part) { return part.score; }), passed: overallState.value === "passed" }; + } + + var resultForSharing = computed(function () { + if (sharedResult.value) return sharedResult.value; + if (view.value !== "summary") return null; + return shareableSessionResult(); + }); + + function buildResultUrl(result) { + if (!result) return ""; + var imageCode = resultImageCode(result); + var url = new URL(imageCode ? "result-" + imageCode + ".html" : "result.html", window.location.href); + url.search = "?result=" + encodedResult(result); + return url.toString(); + } + + var completedResultUrl = computed(function () { + return buildResultUrl(shareableSessionResult()); }); var resultShareUrl = computed(function () { - if (!resultForSharing.value) return ""; - var url = new URL("simulation.html", window.location.href); - url.search = "?result=" + encodedResult(resultForSharing.value); - return url.toString(); + return buildResultUrl(resultForSharing.value); + }); + + var resultImageUrl = computed(function () { + var imageCode = resultImageCode(resultForSharing.value); + return imageCode ? "assets/images/exam-" + imageCode + ".jpeg" : ""; }); var shareText = computed(function () { @@ -654,17 +692,7 @@ navigator.share({ title: "50ohm.de-Ergebnis", text: shareText.value, url: resultShareUrl.value }).catch(function () {}); } - function shareMatrix() { - if (navigator.share) { - navigator.share({ title: "50ohm.de-Ergebnis", text: shareText.value, url: resultShareUrl.value }).catch(function () {}); - return; - } - copyText(shareText.value + " " + resultShareUrl.value).finally(function () { - window.open("https://chat.darc.de", "_blank", "noopener"); - }); - } - - function restoreSession(homeworkQuestionIds) { + function restoreSession(homeworkQuestionIds, allowHomeworkResult) { try { var raw = window.localStorage.getItem(STORAGE_KEY); if (!raw) return; @@ -675,8 +703,8 @@ } var homeworkMode = stored.session.mode === "homework"; var choice = EXAM_CHOICES.find(function (item) { return item.id === stored.session.choiceId; }); - var homeworkMatches = homeworkMode && homeworkQuestionIds.length > 0 && - JSON.stringify(stored.session.homeworkIds) === JSON.stringify(homeworkQuestionIds); + var homeworkMatches = homeworkMode && (allowHomeworkResult || (homeworkQuestionIds.length > 0 && + JSON.stringify(stored.session.homeworkIds) === JSON.stringify(homeworkQuestionIds))); var valid = (homeworkMatches || choice) && stored.session.parts.every(function (part) { return Array.isArray(part.questions) && (homeworkMode || part.questions.length === QUESTION_COUNT) && part.questions.every(function (question) { return Boolean(catalog.value[question.id]); @@ -743,8 +771,16 @@ var homeworkQuestionIds = parseHomeworkQuestionIds(); if (queryValue("result")) { if (!parsedResult) throw new Error("Der Ergebnislink ist ungültig."); - sharedResult.value = parsedResult; - view.value = "shared"; + restoreSession([], true); + var storedResult = shareableSessionResult(); + if (storedResult && encodedResult(storedResult) === queryValue("result")) { + sharedResult.value = null; + view.value = "summary"; + } else { + session.value = null; + sharedResult.value = parsedResult; + view.value = "shared"; + } } else { restoreSession(homeworkQuestionIds); if (homeworkQuestionIds.length > 0 && !session.value) startHomework(homeworkQuestionIds); @@ -841,12 +877,13 @@ resultIcon: resultIcon, resultDescription: resultDescription, resultForSharing: resultForSharing, + completedResultUrl: completedResultUrl, resultShareUrl: resultShareUrl, + resultImageUrl: resultImageUrl, shareText: shareText, socialShareLinks: socialShareLinks, copyResultLink: copyResultLink, - shareNative: shareNative, - shareMatrix: shareMatrix + shareNative: shareNative }; } }); diff --git a/assets/images/exam-a.jpeg b/assets/images/exam-a.jpeg new file mode 100644 index 0000000..5182137 Binary files /dev/null and b/assets/images/exam-a.jpeg differ diff --git a/assets/images/exam-ae.jpeg b/assets/images/exam-ae.jpeg new file mode 100644 index 0000000..aaad91f Binary files /dev/null and b/assets/images/exam-ae.jpeg differ diff --git a/assets/images/exam-aen.jpeg b/assets/images/exam-aen.jpeg new file mode 100644 index 0000000..fb0d9cd Binary files /dev/null and b/assets/images/exam-aen.jpeg differ diff --git a/assets/images/exam-aenb.jpeg b/assets/images/exam-aenb.jpeg new file mode 100644 index 0000000..fd6dbdf Binary files /dev/null and b/assets/images/exam-aenb.jpeg differ diff --git a/assets/images/exam-aenbv.jpeg b/assets/images/exam-aenbv.jpeg new file mode 100644 index 0000000..483362f Binary files /dev/null and b/assets/images/exam-aenbv.jpeg differ diff --git a/assets/images/exam-b.jpeg b/assets/images/exam-b.jpeg new file mode 100644 index 0000000..1ab7dd7 Binary files /dev/null and b/assets/images/exam-b.jpeg differ diff --git a/assets/images/exam-e.jpeg b/assets/images/exam-e.jpeg new file mode 100644 index 0000000..37b3d3a Binary files /dev/null and b/assets/images/exam-e.jpeg differ diff --git a/assets/images/exam-enbv.jpeg b/assets/images/exam-enbv.jpeg new file mode 100644 index 0000000..6a95510 Binary files /dev/null and b/assets/images/exam-enbv.jpeg differ diff --git a/assets/images/exam-n.jpeg b/assets/images/exam-n.jpeg new file mode 100644 index 0000000..9b2a6c3 Binary files /dev/null and b/assets/images/exam-n.jpeg differ diff --git a/assets/images/exam-nbv.jpeg b/assets/images/exam-nbv.jpeg new file mode 100644 index 0000000..2221417 Binary files /dev/null and b/assets/images/exam-nbv.jpeg differ diff --git a/assets/images/exam-v.jpeg b/assets/images/exam-v.jpeg new file mode 100644 index 0000000..e83c54a Binary files /dev/null and b/assets/images/exam-v.jpeg differ diff --git a/src/build.py b/src/build.py index 33af3cb..ba5af98 100644 --- a/src/build.py +++ b/src/build.py @@ -129,6 +129,7 @@ class Build: sidebar=None, page_stylesheets=None, page_scripts=None, + social_image=None, ): page_template = self.env.get_template("html/page.html") return page_template.render( @@ -137,6 +138,7 @@ class Build: sidebar=sidebar, page_stylesheets=page_stylesheets or [], page_scripts=page_scripts or [], + social_image=social_image, ) def __build_exam_simulator(self): @@ -163,11 +165,28 @@ class Build: page_scripts=[ "assets/vue.global.prod.js", "assets/question-catalog.js?ts=20260806", - "assets/exam-simulator.js?ts=20260806", + "assets/exam-simulator.js?ts=202608063", ], ) with (self.config.p_build / "simulation.html").open("w", encoding="utf-8") as file: file.write(page) + with (self.config.p_build / "result.html").open("w", encoding="utf-8") as file: + file.write(page) + + for social_image in sorted((self.config.p_assets / "images").glob("exam-*.jpeg")): + result_page = self.__build_page( + content, + page_stylesheets=["assets/exam-simulator.css?ts=20260806"], + page_scripts=[ + "assets/vue.global.prod.js", + "assets/question-catalog.js?ts=20260806", + "assets/exam-simulator.js?ts=202608063", + ], + social_image=f"assets/images/{social_image.name}", + ) + result_name = f"result-{social_image.stem.removeprefix('exam-')}.html" + with (self.config.p_build / result_name).open("w", encoding="utf-8") as file: + file.write(result_page) def __build_homework_tool(self): toc_target = self.config.p_build_assets / "toc" @@ -182,7 +201,7 @@ class Build: page_scripts=[ "assets/vue.global.prod.js", "assets/question-catalog.js?ts=20260806", - "assets/homework.js?ts=20260806", + "assets/homework.js?ts=202608061", ], ) with (self.config.p_build / "hausaufgabe.html").open("w", encoding="utf-8") as file: diff --git a/templates/html/exam-simulator.html b/templates/html/exam-simulator.html index eb5f27c..c323538 100644 --- a/templates/html/exam-simulator.html +++ b/templates/html/exam-simulator.html @@ -36,16 +36,19 @@ + 50ohm.de-Prüfungssimulation

Ergebnis teilen

- + - Mastodon Bluesky Facebook - X + X (ehem. Twitter)
@@ -145,16 +148,19 @@ + 50ohm.de-Prüfungssimulation

Ergebnis teilen

- + - Mastodon Bluesky Facebook - X + X (ehem. Twitter)
@@ -191,8 +197,9 @@ Abgegeben - + @@ -259,7 +266,8 @@ diff --git a/templates/html/page.html b/templates/html/page.html index 6f8146c..163fc24 100644 --- a/templates/html/page.html +++ b/templates/html/page.html @@ -4,6 +4,21 @@ 50Ω Lernplattform für Amateurfunk + {% if social_image %} + + + + + + + + + + + + + + {% endif %}