diff --git a/game/migrations/0101_update_python_den_level_41.py b/game/migrations/0101_update_python_den_level_41.py
new file mode 100644
index 000000000..3fbb0d6f0
--- /dev/null
+++ b/game/migrations/0101_update_python_den_level_41.py
@@ -0,0 +1,26 @@
+from django.apps.registry import Apps
+from django.db import migrations
+
+def update_python_den_level_41(apps: Apps, *args):
+ Level = apps.get_model("game", "Level")
+
+ level41 = Level.objects.get(default=True, name="1041")
+ level41.next_level = None
+ level41.save()
+
+def revert_python_den_level_41(apps: Apps, *args):
+ Level = apps.get_model("game", "Level")
+
+ level41 = Level.objects.get(default=True, name="1041")
+ level41.next_level = Level.objects.get(default=True, name="1042")
+ level41.save()
+
+class Migration(migrations.Migration):
+ dependencies = [("game", "0100_reorder_python_levels")]
+
+ operations = [
+ migrations.RunPython(
+ code=update_python_den_level_41,
+ reverse_code=revert_python_den_level_41
+ )
+ ]
\ No newline at end of file
diff --git a/game/static/game/js/animation.js b/game/static/game/js/animation.js
index 2422a1237..e57fe656b 100644
--- a/game/static/game/js/animation.js
+++ b/game/static/game/js/animation.js
@@ -318,7 +318,11 @@ ocargo.Animation.prototype.performAnimation = function(animation) {
} else {
// If there exists next level, add animation button which redirects the user to that
if (NEXT_LEVEL_URL) {
- buttons += ocargo.button.redirectButtonHtml('next_level_button', NEXT_LEVEL_URL, gettext('Next level'));
+ if (NEXT_LEVEL_URL == "/pythonden/") {
+ buttons += ocargo.button.episodeRedirectButtonHtml('next_level_button', NEXT_LEVEL_URL, gettext('Next episode'), NEXT_EPISODE)
+ } else {
+ buttons += ocargo.button.redirectButtonHtml('next_level_button', NEXT_LEVEL_URL, gettext('Next level'))
+ }
}
else if (PREV_LEVEL_URL) {
buttons += ocargo.button.redirectButtonHtml('prev_level_button', PREV_LEVEL_URL, gettext('Previous level'));
diff --git a/game/static/game/js/button.js b/game/static/game/js/button.js
index 5621b7f7c..372f56b01 100644
--- a/game/static/game/js/button.js
+++ b/game/static/game/js/button.js
@@ -14,6 +14,18 @@ ocargo.button.redirectButtonHtml = function(id, location, label){
return Handlebars.templates['button-redirect']({id: id, location: location, label: label});
};
+// Returns the html code for a button which redirects to a given episode on the level selection page
+ocargo.button.episodeRedirectButtonHtml = function(id, location, label, next_episode){
+ return ``
+}
+
// Returns the html code for a button which shows the try again message and closes the popup
ocargo.button.tryAgainButtonHtml = function(){
return ocargo.button.dismissButtonHtml('try_again_button', gettext('Try again'));
diff --git a/game/static/game/js/drawing.js b/game/static/game/js/drawing.js
index e1c23c76b..fc6d55f3d 100644
--- a/game/static/game/js/drawing.js
+++ b/game/static/game/js/drawing.js
@@ -1104,7 +1104,9 @@ ocargo.Drawing.startPopup = function (
// adding links to buttons
currentButton.append(icons[i])
let currentLink = links[i] === "" ? "" : `window.location.replace('${links[i]}')`
- currentButton.attr("onclick", currentLink)
+ if (currentID !== "next_button") {
+ currentButton.attr("onclick", currentLink);
+ }
}
// Close the video on the play button
diff --git a/game/static/game/js/game.js b/game/static/game/js/game.js
index f760b80df..0819e5b5d 100644
--- a/game/static/game/js/game.js
+++ b/game/static/game/js/game.js
@@ -145,6 +145,9 @@ ocargo.Game.prototype.setup = function () {
const showMascot = BLOCKLY_ENABLED && !PYTHON_VIEW_ENABLED && LEVEL_NAME <= 80; // show mascot on Blockly-only levels that are not above 80
const subtitle = SUBTITLE == "None" ? "" : "" + SUBTITLE + "
";
+ const next_button_html = NEXT_LEVEL_URL == "/pythonden/"
+ ? ocargo.button.episodeRedirectButtonHtml("next_button", NEXT_LEVEL_URL, gettext('Next episode'), NEXT_EPISODE)
+ : ocargo.button.dismissButtonHtml("next_button", gettext('Next level'))
ocargo.Drawing.startPopup(
title,
subtitle + LESSON,
@@ -153,7 +156,7 @@ ocargo.Game.prototype.setup = function () {
[
ocargo.button.dismissButtonHtml("prev_button", gettext("Previous level")),
ocargo.button.dismissButtonHtml('play_button', gettext('Play')),
- ocargo.button.dismissButtonHtml("next_button", gettext("Next level"))
+ next_button_html
]
)
}
@@ -162,6 +165,7 @@ ocargo.Game.prototype.setup = function () {
document.addEventListener("DOMContentLoaded", function() {
const dataElement = document.getElementById('data');
const currentEpisode = dataElement ? dataElement.getAttribute('data-episode') : null;
+ console.log(currentEpisode);
if (currentEpisode) {
localStorage.setItem('currentEpisode', currentEpisode);
}
diff --git a/game/views/level.py b/game/views/level.py
index ac04a8dcb..946b0237d 100644
--- a/game/views/level.py
+++ b/game/views/level.py
@@ -93,7 +93,10 @@ def _next_level_url(level, user, night_mode, from_python_den):
the teacher has locked certain levels, then loop until we find the next
unlocked level (or we run out of levels).
"""
+
if not level.next_level:
+ if level.episode.pk == 13:
+ return reverse("python_levels")
return ""
next_level = level.next_level