diff --git a/Pipfile b/Pipfile
index a8ef335c1..afdb4bb73 100644
--- a/Pipfile
+++ b/Pipfile
@@ -9,11 +9,13 @@ ipython = "*"
rapid-router = {path = ".", editable = true}
[dev-packages]
+black = "*"
codeforlife-portal = "*"
django-import-export = "*"
django-selenium-clean = "==1.0.0"
django-test-migrations = "==1.2.0"
importlib-metadata = "<5" # Using version 5 causes an issue when trying to run pytest. Not sure why, linked to: https://stackoverflow.com/questions/73929564/entrypoints-object-has-no-attribute-get-digital-ocean
+isort = "*"
pytest = "==7.*"
pytest-django = "==4.5.2"
pytest-order = "*"
diff --git a/Pipfile.lock b/Pipfile.lock
index 51d84816a..7937ea228 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "f226d4b94222f73959f2d2a2ca01b487d4d58f7f188553141389208e98bce1ca"
+ "sha256": "95dccb04c57f2209160bd30a130b5eaaf58cbaaf038d32faf7f0fe919a3db538"
},
"pipfile-spec": 6,
"requires": {
@@ -464,7 +464,7 @@
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0.post0"
},
"pytz": {
@@ -499,7 +499,7 @@
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0"
},
"sqlparse": {
@@ -589,6 +589,35 @@
"markers": "python_version >= '3.7'",
"version": "==23.2.0"
},
+ "black": {
+ "hashes": [
+ "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474",
+ "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1",
+ "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0",
+ "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8",
+ "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96",
+ "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1",
+ "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04",
+ "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021",
+ "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94",
+ "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d",
+ "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c",
+ "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7",
+ "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c",
+ "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc",
+ "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7",
+ "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d",
+ "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c",
+ "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741",
+ "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce",
+ "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb",
+ "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063",
+ "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==24.4.2"
+ },
"cachetools": {
"hashes": [
"sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945",
@@ -708,6 +737,14 @@
"markers": "python_full_version >= '3.7.0'",
"version": "==3.3.2"
},
+ "click": {
+ "hashes": [
+ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
+ "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==8.1.7"
+ },
"codeforlife-portal": {
"hashes": [
"sha256:64c51f8a42c488930fc5e0b3a0b9d740d7e6c52b69f0f524cb80162a9d36c4db",
@@ -878,6 +915,7 @@
"sha256:27ae41fad9deed9bbf4166f3e3b65acc15d524d42210a518e5877da85a6b8c5d",
"sha256:b36ec2ecc003de87fc87b93197d77fea528aa0f9204a34fdf3b2f8d0f01e017b"
],
+ "markers": "python_version >= '3.7'",
"version": "==0.31.0"
},
"exceptiongroup": {
@@ -1009,6 +1047,15 @@
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
},
+ "isort": {
+ "hashes": [
+ "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109",
+ "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"
+ ],
+ "index": "pypi",
+ "markers": "python_full_version >= '3.8.0'",
+ "version": "==5.13.2"
+ },
"kubernetes": {
"hashes": [
"sha256:5854b0c508e8d217ca205591384ab58389abdae608576f9c9afc35a3c76a366c",
@@ -1037,6 +1084,14 @@
"markers": "python_version >= '3.5'",
"version": "==8.7.0"
},
+ "mypy-extensions": {
+ "hashes": [
+ "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
+ "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
+ ],
+ "markers": "python_version >= '3.5'",
+ "version": "==1.0.0"
+ },
"numpy": {
"hashes": [
"sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f",
@@ -1126,6 +1181,14 @@
"markers": "python_version >= '3.8'",
"version": "==2.0.3"
},
+ "pathspec": {
+ "hashes": [
+ "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08",
+ "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==0.12.1"
+ },
"pgeocode": {
"hashes": [
"sha256:07995d4cd2d7fec1f82afb14d6025e83bbc156b6f225fa3e0b3417da2ec020c8",
@@ -1216,6 +1279,14 @@
"markers": "python_version >= '3.8'",
"version": "==10.3.0"
},
+ "platformdirs": {
+ "hashes": [
+ "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf",
+ "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==4.2.1"
+ },
"pluggy": {
"hashes": [
"sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1",
@@ -1312,7 +1383,7 @@
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0.post0"
},
"pytz": {
@@ -1466,7 +1537,7 @@
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0"
},
"sniffio": {
diff --git a/game/end_to_end_tests/base_game_test.py b/game/end_to_end_tests/base_game_test.py
index e03398826..d555196f5 100644
--- a/game/end_to_end_tests/base_game_test.py
+++ b/game/end_to_end_tests/base_game_test.py
@@ -87,14 +87,12 @@ def go_to_homepage(self):
def go_to_level(self, level_name):
path = reverse("play_default_level", kwargs={"levelName": str(level_name)})
self._go_to_path(path)
- self.selenium.execute_script("ocargo.animation.FAST_ANIMATION_DURATION = 1;")
return GamePage(self.selenium)
def go_to_custom_level(self, level):
path = reverse("play_custom_level", kwargs={"levelId": str(level.id)})
self._go_to_path(path)
- self.selenium.execute_script("ocargo.animation.FAST_ANIMATION_DURATION = 1;")
return GamePage(self.selenium)
@@ -106,7 +104,6 @@ def go_to_level_editor(self):
def go_to_episode(self, episodeId):
path = reverse("start_episode", kwargs={"episodeId": str(episodeId)})
self._go_to_path(path)
- self.selenium.execute_script("ocargo.animation.FAST_ANIMATION_DURATION = 1;")
return GamePage(self.selenium)
diff --git a/game/end_to_end_tests/game_page.py b/game/end_to_end_tests/game_page.py
index 804c37ed0..e76a7d7d8 100644
--- a/game/end_to_end_tests/game_page.py
+++ b/game/end_to_end_tests/game_page.py
@@ -19,6 +19,8 @@ class GamePage(BasePage):
def __init__(self, browser):
super(GamePage, self).__init__(browser)
+ self.browser.execute_script("ocargo.animation.FAST_ANIMATION_DURATION = 1;")
+
assert self.on_correct_page("game_page")
self._dismiss_initial_dialog()
diff --git a/game/end_to_end_tests/test_language_dropdown.py b/game/end_to_end_tests/test_language_dropdown.py
new file mode 100644
index 000000000..4c9d43418
--- /dev/null
+++ b/game/end_to_end_tests/test_language_dropdown.py
@@ -0,0 +1,14 @@
+from game.end_to_end_tests.base_game_test import BaseGameTest
+
+from selenium.webdriver.common.by import By
+
+class TestLanguageDropdown(BaseGameTest):
+ def test_level_language_dropdown(self):
+ page = self.go_to_level(1)
+ assert page.element_exists_by_id("language_dropdown")
+
+ self.selenium.find_element(By.ID, "language_dropdown").click()
+ self.selenium.find_element(By.ID, "language_dropdown_fr").click()
+
+ text_count = len(self.selenium.find_elements(By.XPATH, ("//*[contains(text(),'Move forwards')]")))
+ assert text_count == 0
diff --git a/game/static/game/css/backgrounds.css b/game/static/game/css/backgrounds.css
index b661f5e86..69c7e1c07 100644
--- a/game/static/game/css/backgrounds.css
+++ b/game/static/game/css/backgrounds.css
@@ -1,37 +1,37 @@
/* Background colours for episodes and game sidebar */
.bg--easy {
- background: #86ae18;
+ background-color: #86ae18;
}
.bg--medium {
- background: #00a3e0;
+ background-color: #00a3e0;
}
.bg--medium-hard {
- background: #008cc1;
+ background-color: #008cc1;
}
.bg--brainteasers {
- background: #c90548;
+ background-color: #c90548;
}
.bg--hard {
- background: #8967d3;
+ background-color: #8967d3;
}
.bg--advanced {
- background: #754fc8;
+ background-color: #754fc8;
}
.bg--shared-levels {
- background: #f6be00;
+ background-color: #f6be00;
}
.bg--loops {
- background: #3F3F3F;
+ background-color: #3F3F3F;
}
.bg--loops-coming-soon {
- background: #CBCBCB;
+ background-color: #CBCBCB;
}
diff --git a/game/static/game/css/game_screen.css b/game/static/game/css/game_screen.css
index 549667581..79e371a74 100644
--- a/game/static/game/css/game_screen.css
+++ b/game/static/game/css/game_screen.css
@@ -430,6 +430,17 @@ div.no-print div.tab label {
background: rgba(255, 255, 255, 0.25);
}
+.tab select:hover {
+ background: rgba(255, 255, 255, 0.25);
+}
+
+.tab select {
+ color: black;
+ border: none;
+ font-weight: bold;
+ padding-right: 20px;
+}
+
#console {
z-index: 100;
display: flex;
diff --git a/game/static/game/js/blockly/msg/js/en-gb.js b/game/static/game/js/blockly/msg/js/en-gb.js
index e22384b06..9f49d8360 100755
--- a/game/static/game/js/blockly/msg/js/en-gb.js
+++ b/game/static/game/js/blockly/msg/js/en-gb.js
@@ -433,4 +433,53 @@ Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
-Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
\ No newline at end of file
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+Blockly.Msg["START_TITLE"] = "Start";
+Blockly.Msg["START_TOOLTIP"] = "The beginning of the program"
+Blockly.Msg["MOVE_FORWARDS_TITLE"] = "move forwards";
+Blockly.Msg["MOVE_FORWARDS_TOOLTIP"] = "Move the van forwards";
+Blockly.Msg["TURN_LEFT_TITLE"] = "turn left";
+Blockly.Msg["TURN_LEFT_TOOLTIP"] = "Turn the van left";
+Blockly.Msg["TURN_RIGHT_TITLE"] = "turn right";
+Blockly.Msg["TURN_RIGHT_TOOLTIP"] = "Turn the van right";
+Blockly.Msg["TURN_AROUND_TITLE"] = "turn around";
+Blockly.Msg["TURN_AROUND_TOOLTIP"] = "Turn the van around";
+
+Blockly.Msg["WAIT_TITLE"] = "wait";
+Blockly.Msg["WAIT_TOOLTIP"] = "Keep the van stationary";
+Blockly.Msg["DELIVER_TITLE"] = "deliver";
+Blockly.Msg["DELIVER_TOOLTIP"] = "Deliver the goods from the van";
+Blockly.Msg["SOUND_HORN_TITLE"] = "sound horn";
+Blockly.Msg["SOUND_HORN_TOOLTIP"] = "Sound the horn to scare away the cows";
+
+Blockly.Msg["ROAD_EXISTS_FORWARD_TITLE"] = "road exists forward";
+Blockly.Msg["ROAD_EXISTS_LEFT_TITLE"] = "road exists left";
+Blockly.Msg["ROAD_EXISTS_RIGHT_TITLE"] = "road exists right";
+Blockly.Msg["TRAFFIC_LIGHT_RED_TITLE"] = "traffic light red";
+Blockly.Msg["TRAFFIC_LIGHT_GREEN_TITLE"] = "traffic light green";
+Blockly.Msg["DEAD_END_TITLE"] = "is dead end";
+Blockly.Msg["AT_DESTINATION_TITLE"] = "at destination";
+Blockly.Msg["COW_CROSSING_TITLE"] = "cows";
+
+Blockly.Msg["CALL_PROC_TITLE"] = "Call";
+Blockly.Msg["CALL_PROC_TOOLTIP"] = "Calls a procedure";
+Blockly.Msg["DECLARE_PROC_TITLE"] = "Define";
+Blockly.Msg["DECLARE_PROC_TOOLTIP"] = "Declares a procedure";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TITLE"] = "repeat while";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_SUBTITLE"] = "do";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TOOLTIP"] = "While a value is true, do some statements";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TITLE"] = "repeat until";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_SUBTITLE"] = "do";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TOOLTIP"] = "Until a value is true, do some statements";
+
+Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "A variable";
+Blockly.Msg["VARIABLES_SET_TITLE"] = "set";
+Blockly.Msg["VARIABLES_SET_SUBTITLE"] = "to";
+Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Set a variable";
+Blockly.Msg["VARIABLES_NUMERIC_SET_TOOLTIP"] = "Set a variable to a number";
+Blockly.Msg["VARIABLES_INCREMENT_TITLE"] = "increment";
+Blockly.Msg["VARIABLES_INCREMENT_SUBTITLE"] = "by";
+Blockly.Msg["VARIABLES_INCREMENT_TOOLTIP"] = "Increment a variable";
+Blockly.Msg["NUMBER_TITLE"] = "Number";
+Blockly.Msg["NUMBER_TOOLTIP"] = "A number";
\ No newline at end of file
diff --git a/game/static/game/js/blockly/msg/js/en.js b/game/static/game/js/blockly/msg/js/en.js
index 24afa59b7..c71af5cc2 100755
--- a/game/static/game/js/blockly/msg/js/en.js
+++ b/game/static/game/js/blockly/msg/js/en.js
@@ -433,4 +433,53 @@ Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
-Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
\ No newline at end of file
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+Blockly.Msg["START_TITLE"] = "Start";
+Blockly.Msg["START_TOOLTIP"] = "The beginning of the program"
+Blockly.Msg["MOVE_FORWARDS_TITLE"] = "move forwards";
+Blockly.Msg["MOVE_FORWARDS_TOOLTIP"] = "Move the van forwards";
+Blockly.Msg["TURN_LEFT_TITLE"] = "turn left";
+Blockly.Msg["TURN_LEFT_TOOLTIP"] = "Turn the van left";
+Blockly.Msg["TURN_RIGHT_TITLE"] = "turn right";
+Blockly.Msg["TURN_RIGHT_TOOLTIP"] = "Turn the van right";
+Blockly.Msg["TURN_AROUND_TITLE"] = "turn around";
+Blockly.Msg["TURN_AROUND_TOOLTIP"] = "Turn the van around";
+
+Blockly.Msg["WAIT_TITLE"] = "wait";
+Blockly.Msg["WAIT_TOOLTIP"] = "Keep the van stationary";
+Blockly.Msg["DELIVER_TITLE"] = "deliver";
+Blockly.Msg["DELIVER_TOOLTIP"] = "Deliver the goods from the van";
+Blockly.Msg["SOUND_HORN_TITLE"] = "sound horn";
+Blockly.Msg["SOUND_HORN_TOOLTIP"] = "Sound the horn to scare away the cows";
+
+Blockly.Msg["ROAD_EXISTS_FORWARD_TITLE"] = "road exists forward";
+Blockly.Msg["ROAD_EXISTS_LEFT_TITLE"] = "road exists left";
+Blockly.Msg["ROAD_EXISTS_RIGHT_TITLE"] = "road exists right";
+Blockly.Msg["TRAFFIC_LIGHT_RED_TITLE"] = "traffic light red";
+Blockly.Msg["TRAFFIC_LIGHT_GREEN_TITLE"] = "traffic light green";
+Blockly.Msg["DEAD_END_TITLE"] = "is dead end";
+Blockly.Msg["AT_DESTINATION_TITLE"] = "at destination";
+Blockly.Msg["COW_CROSSING_TITLE"] = "cows";
+
+Blockly.Msg["CALL_PROC_TITLE"] = "Call";
+Blockly.Msg["CALL_PROC_TOOLTIP"] = "Calls a procedure";
+Blockly.Msg["DECLARE_PROC_TITLE"] = "Define";
+Blockly.Msg["DECLARE_PROC_TOOLTIP"] = "Declares a procedure";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TITLE"] = "repeat while";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_SUBTITLE"] = "do";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TOOLTIP"] = "While a value is true, do some statements";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TITLE"] = "repeat until";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_SUBTITLE"] = "do";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TOOLTIP"] = "Until a value is true, do some statements";
+
+Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "A variable";
+Blockly.Msg["VARIABLES_SET_TITLE"] = "set";
+Blockly.Msg["VARIABLES_SET_SUBTITLE"] = "to";
+Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Set a variable";
+Blockly.Msg["VARIABLES_NUMERIC_SET_TOOLTIP"] = "Set a variable to a number";
+Blockly.Msg["VARIABLES_INCREMENT_TITLE"] = "increment";
+Blockly.Msg["VARIABLES_INCREMENT_SUBTITLE"] = "by";
+Blockly.Msg["VARIABLES_INCREMENT_TOOLTIP"] = "Increment a variable";
+Blockly.Msg["NUMBER_TITLE"] = "Number";
+Blockly.Msg["NUMBER_TOOLTIP"] = "A number";
\ No newline at end of file
diff --git a/game/static/game/js/blockly/msg/js/fr.js b/game/static/game/js/blockly/msg/js/fr.js
index dce0fe18a..d9fe11e81 100755
--- a/game/static/game/js/blockly/msg/js/fr.js
+++ b/game/static/game/js/blockly/msg/js/fr.js
@@ -433,4 +433,53 @@ Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
-Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
\ No newline at end of file
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+Blockly.Msg["START_TITLE"] = "Départ";
+Blockly.Msg["START_TOOLTIP"] = "Le début du programme"
+Blockly.Msg["MOVE_FORWARDS_TITLE"] = "avancer";
+Blockly.Msg["MOVE_FORWARDS_TOOLTIP"] = "Faire avancer le camion";
+Blockly.Msg["TURN_LEFT_TITLE"] = "tourner à gauche";
+Blockly.Msg["TURN_LEFT_TOOLTIP"] = "Faire tourner le camion à gauche";
+Blockly.Msg["TURN_RIGHT_TITLE"] = "tourner à droite";
+Blockly.Msg["TURN_RIGHT_TOOLTIP"] = "Faire tourner le camion à droite";
+Blockly.Msg["TURN_AROUND_TITLE"] = "faire demi-tour";
+Blockly.Msg["TURN_AROUND_TOOLTIP"] = "Faire demi-tour avec le camion";
+
+Blockly.Msg["WAIT_TITLE"] = "attendre";
+Blockly.Msg["WAIT_TOOLTIP"] = "Faire arrêter le camion pour attendre";
+Blockly.Msg["DELIVER_TITLE"] = "livrer";
+Blockly.Msg["DELIVER_TOOLTIP"] = "Livrer la commande du camion";
+Blockly.Msg["SOUND_HORN_TITLE"] = "klaxonner";
+Blockly.Msg["SOUND_HORN_TOOLTIP"] = "Klaxonner pour effrayer les vaches";
+
+Blockly.Msg["ROAD_EXISTS_FORWARD_TITLE"] = "la route existe en face";
+Blockly.Msg["ROAD_EXISTS_LEFT_TITLE"] = "la route existe à gauche";
+Blockly.Msg["ROAD_EXISTS_RIGHT_TITLE"] = "la route existe à droite";
+Blockly.Msg["TRAFFIC_LIGHT_RED_TITLE"] = "feu rouge";
+Blockly.Msg["TRAFFIC_LIGHT_GREEN_TITLE"] = "feu vert";
+Blockly.Msg["DEAD_END_TITLE"] = "cul-de-sac";
+Blockly.Msg["AT_DESTINATION_TITLE"] = "arrivé à destination";
+Blockly.Msg["COW_CROSSING_TITLE"] = "vaches";
+
+Blockly.Msg["CALL_PROC_TITLE"] = "Appeler";
+Blockly.Msg["CALL_PROC_TOOLTIP"] = "Appeler une fonction";
+Blockly.Msg["DECLARE_PROC_TITLE"] = "Définir";
+Blockly.Msg["DECLARE_PROC_TOOLTIP"] = "Déclarer une fonction";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TITLE"] = "répéter tant que";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_SUBTITLE"] = "faire";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TOOLTIP"] = "Tant qu’une valeur est vraie, faire des instructions";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TITLE"] = "répéter jusqu’à ce que";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_SUBTITLE"] = "faire";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TOOLTIP"] = "Jusqu’à ce qu’une valeur soit vraie, faire des instructions";
+
+Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Une variable";
+Blockly.Msg["VARIABLES_SET_TITLE"] = "définir";
+Blockly.Msg["VARIABLES_SET_SUBTITLE"] = "à";
+Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Définir une variable";
+Blockly.Msg["VARIABLES_NUMERIC_SET_TOOLTIP"] = "Définir une variable à un nombre";
+Blockly.Msg["VARIABLES_INCREMENT_TITLE"] = "incrémenter";
+Blockly.Msg["VARIABLES_INCREMENT_SUBTITLE"] = "de";
+Blockly.Msg["VARIABLES_INCREMENT_TOOLTIP"] = "Incrémenter une variable";
+Blockly.Msg["NUMBER_TITLE"] = "nombre";
+Blockly.Msg["NUMBER_TOOLTIP"] = "Un nombre";
\ No newline at end of file
diff --git a/game/static/game/js/blockly/msg/js/hi.js b/game/static/game/js/blockly/msg/js/hi.js
index 177b255cb..a783b7c24 100755
--- a/game/static/game/js/blockly/msg/js/hi.js
+++ b/game/static/game/js/blockly/msg/js/hi.js
@@ -433,4 +433,53 @@ Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
-Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
\ No newline at end of file
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+Blockly.Msg["START_TITLE"] = "शुरू";
+Blockly.Msg["START_TOOLTIP"] = "कार्यक्रम की शुरुआत";
+Blockly.Msg["MOVE_FORWARDS_TITLE"] = "आगे बढ़ें";
+Blockly.Msg["MOVE_FORWARDS_TOOLTIP"] = "वैन को आगे बढ़ाएं";
+Blockly.Msg["TURN_LEFT_TITLE"] = "बाएँ मुड़ें";
+Blockly.Msg["TURN_LEFT_TOOLTIP"] = "वैन को बाएँ मोड़ें";
+Blockly.Msg["TURN_RIGHT_TITLE"] = "दाएं मुड़ें";
+Blockly.Msg["TURN_RIGHT_TOOLTIP"] = "वैन को दाएं मोड़ें)";
+Blockly.Msg["TURN_AROUND_TITLE"] = "मुड़ो";
+Blockly.Msg["TURN_AROUND_TOOLTIP"] = "वैन को घुमाओ";
+
+Blockly.Msg["WAIT_TITLE"] = "इंतज़ार";
+Blockly.Msg["WAIT_TOOLTIP"] = "वैन को स्थिर रखें";
+Blockly.Msg["DELIVER_TITLE"] = "बाँटना";
+Blockly.Msg["DELIVER_TOOLTIP"] = "वैन से सामान पहुंचाएं";
+Blockly.Msg["SOUND_HORN_TITLE"] = "हॉर्न बजाओ";
+Blockly.Msg["SOUND_HORN_TOOLTIP"] = "गायों को डराने के लिए हॉर्न बजाएं";
+
+Blockly.Msg["ROAD_EXISTS_FORWARD_TITLE"] = "सड़क आगे मौजूद है";
+Blockly.Msg["ROAD_EXISTS_LEFT_TITLE"] = "सड़क बाएँ मौजूद है";
+Blockly.Msg["ROAD_EXISTS_RIGHT_TITLE"] = "सड़क दाएँ मौजूद है";
+Blockly.Msg["TRAFFIC_LIGHT_RED_TITLE"] = "ट्रैफिक लाइट लाल";
+Blockly.Msg["TRAFFIC_LIGHT_GREEN_TITLE"] = "ट्रैफिक लाइट हरा";
+Blockly.Msg["DEAD_END_TITLE"] = "आगे का रास्ता बंद है";
+Blockly.Msg["AT_DESTINATION_TITLE"] = "मंजिल /गंतव्य पर";
+Blockly.Msg["COW_CROSSING_TITLE"] = "गायों";
+
+Blockly.Msg["CALL_PROC_TITLE"] = "पुकारना";
+Blockly.Msg["CALL_PROC_TOOLTIP"] = "एक प्रक्रिया बुलाना";
+Blockly.Msg["DECLARE_PROC_TITLE"] = "परिभाषित करना";
+Blockly.Msg["DECLARE_PROC_TOOLTIP"] = "प्रक्रिया की घोषणा करता है";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TITLE"] = "दोहराएँ जबकि";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_SUBTITLE"] = "करो";
+Blockly.Msg["CONTROLS_REPEAT_WHILE_TOOLTIP"] = "जबकि कोई मान सत्य है, कुछ कथन करें";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TITLE"] = "जब तक";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_SUBTITLE"] = "न करें तब तक दोहराएँ";
+Blockly.Msg["CONTROLS_REPEAT_UNTIL_TOOLTIP"] = "जब तक कोई मान सत्य न हो, कुछ कथन करें";
+
+Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "एक परिवर्तनीय";
+Blockly.Msg["VARIABLES_SET_TITLE"] = "तय करना";
+Blockly.Msg["VARIABLES_SET_SUBTITLE"] = "को";
+Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "एक परिवर्तनीय तय करना";
+Blockly.Msg["VARIABLES_NUMERIC_SET_TOOLTIP"] = "एक परिवर्तनीय को एक संख्या पर तय करें";
+Blockly.Msg["VARIABLES_INCREMENT_TITLE"] = "बढ़ाई";
+Blockly.Msg["VARIABLES_INCREMENT_SUBTITLE"] = "द्वारा";
+Blockly.Msg["VARIABLES_INCREMENT_TOOLTIP"] = "एक वेरिएबल बढ़ाएँ";
+Blockly.Msg["NUMBER_TITLE"] = "संख्या";
+Blockly.Msg["NUMBER_TOOLTIP"] = "एक संख्या";
\ No newline at end of file
diff --git a/game/static/game/js/blocklyControl.js b/game/static/game/js/blocklyControl.js
index f3ade14ba..21149ab9f 100644
--- a/game/static/game/js/blocklyControl.js
+++ b/game/static/game/js/blocklyControl.js
@@ -8,6 +8,7 @@ ocargo.BlocklyControl = function () {
this.blocklyCustomisations.setupLimitedBlocks();
this.blocklyDiv = document.getElementById("blockly_holder");
this.toolbox = document.getElementById("blockly_toolbox");
+
Blockly.inject(this.blocklyDiv, {
path: "/static/game/js/blockly/",
toolbox: BLOCKLY_XML,
@@ -434,4 +435,4 @@ ocargo.BlockHandler.prototype.deselectCurrent = function () {
this.setBlockSelected(this.selectedBlock, false);
this.selectedBlock = null;
}
-};
+};
\ No newline at end of file
diff --git a/game/static/game/js/blocklyCustomBlocks.js b/game/static/game/js/blocklyCustomBlocks.js
index 7818a4e89..8f5458b06 100644
--- a/game/static/game/js/blocklyCustomBlocks.js
+++ b/game/static/game/js/blocklyCustomBlocks.js
@@ -15,7 +15,7 @@ function initCustomBlocksDescription() {
ocargo.blocklyControl.numStartBlocks++;
this.setColour(50);
this.appendDummyInput()
- .appendField(gettext("Start"))
+ .appendField(Blockly.Msg.START_TITLE)
.appendField(new Blockly.FieldImage(
new Date().getMonth() === 11 && CHARACTER_NAME === "Van"
? ocargo.Drawing.imageDir + "characters/top_view/Sleigh.svg"
@@ -25,7 +25,7 @@ function initCustomBlocksDescription() {
)
);
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("The beginning of the program"));
+ this.setTooltip(Blockly.Msg.START_TOOLTIP);
this.setDeletable(false);
},
};
@@ -39,7 +39,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("move forwards"))
+ .appendField(Blockly.Msg.MOVE_FORWARDS_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "actions/forward.svg",
@@ -49,7 +49,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Move the van forwards"));
+ this.setTooltip(Blockly.Msg.MOVE_FORWARDS_TOOLTIP);
},
};
@@ -58,7 +58,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("turn left"))
+ .appendField(Blockly.Msg.TURN_LEFT_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -75,7 +75,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Turn the van left"));
+ this.setTooltip(Blockly.Msg.TURN_LEFT_TOOLTIP);
},
};
@@ -84,7 +84,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("turn right"))
+ .appendField(Blockly.Msg.TURN_RIGHT_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -101,7 +101,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Turn the van right"));
+ this.setTooltip(Blockly.Msg.TURN_RIGHT_TOOLTIP);
},
};
@@ -110,7 +110,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("turn around"))
+ .appendField(Blockly.Msg.TURN_AROUND_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -127,7 +127,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Turn the van around"));
+ this.setTooltip(Blockly.Msg.TURN_AROUND_TOOLTIP);
},
};
@@ -136,7 +136,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("wait"))
+ .appendField(Blockly.Msg.WAIT_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -153,7 +153,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Keep the van stationary"));
+ this.setTooltip(Blockly.Msg.WAIT_TOOLTIP);
},
};
@@ -162,7 +162,7 @@ function initCustomBlocksDescription() {
init: function () {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext("deliver"))
+ .appendField(Blockly.Msg.DELIVER_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -179,7 +179,7 @@ function initCustomBlocksDescription() {
);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Deliver the goods from the van"));
+ this.setTooltip(Blockly.Msg.DELIVER_TOOLTIP);
},
};
@@ -187,7 +187,7 @@ function initCustomBlocksDescription() {
init: function() {
this.setColour(160);
this.appendDummyInput()
- .appendField(gettext('sound horn'))
+ .appendField(Blockly.Msg.SOUND_HORN_TITLE)
.appendField(new Blockly.FieldImage(ocargo.Drawing.imageDir + 'empty.svg',
43,
ocargo.BlocklyControl.BLOCK_HEIGHT))
@@ -196,7 +196,7 @@ function initCustomBlocksDescription() {
ocargo.BlocklyControl.BLOCK_HEIGHT));
this.setPreviousStatement(true, 'Action');
this.setNextStatement(true, 'Action');
- this.setTooltip(gettext('Sound the horn to scare away the cows'));
+ this.setTooltip(Blockly.Msg.SOUND_HORN_TOOLTIP);
}
};
@@ -207,9 +207,9 @@ function initCustomBlocksDescription() {
Blockly.Blocks["road_exists"] = {
init: function () {
var BOOLEANS = [
- [gettext("road exists forward"), "FORWARD"],
- [gettext("road exists left"), "LEFT"],
- [gettext("road exists right"), "RIGHT"],
+ [Blockly.Msg.ROAD_EXISTS_FORWARD_TITLE, "FORWARD"],
+ [Blockly.Msg.ROAD_EXISTS_LEFT_TITLE, "LEFT"],
+ [Blockly.Msg.ROAD_EXISTS_RIGHT_TITLE, "RIGHT"],
];
this.setColour(210);
this.setOutput(true, "Boolean");
@@ -228,8 +228,8 @@ function initCustomBlocksDescription() {
Blockly.Blocks["traffic_light"] = {
init: function () {
var BOOLEANS = [
- [gettext("traffic light red"), ocargo.TrafficLight.RED],
- [gettext("traffic light green"), ocargo.TrafficLight.GREEN],
+ [Blockly.Msg.TRAFFIC_LIGHT_RED_TITLE, ocargo.TrafficLight.RED],
+ [Blockly.Msg.TRAFFIC_LIGHT_GREEN_TITLE, ocargo.TrafficLight.GREEN],
];
this.setColour(210);
this.setOutput(true, "Boolean");
@@ -250,7 +250,7 @@ function initCustomBlocksDescription() {
this.setColour(210);
this.setOutput(true, "Boolean");
this.appendDummyInput()
- .appendField(gettext("is dead end"))
+ .appendField(Blockly.Msg.DEAD_END_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -266,7 +266,7 @@ function initCustomBlocksDescription() {
this.setColour(210);
this.setOutput(true, "Boolean");
this.appendDummyInput()
- .appendField(gettext("at destination"))
+ .appendField(Blockly.Msg.AT_DESTINATION_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -282,7 +282,7 @@ function initCustomBlocksDescription() {
this.setColour(210);
this.setOutput(true, 'Boolean');
this.appendDummyInput()
- .appendField(gettext('cows'))
+ .appendField(Blockly.Msg.COW_CROSSING_TITLE)
.appendField(new Blockly.FieldImage(ocargo.Drawing.imageDir + ocargo.Drawing.whiteCowUrl,
ocargo.BlocklyControl.COW_WIDTH,
ocargo.BlocklyControl.BLOCK_HEIGHT), 'IMAGE');
@@ -298,7 +298,7 @@ function initCustomBlocksDescription() {
var name = "";
this.setColour(260);
this.appendDummyInput()
- .appendField(gettext("Call"))
+ .appendField(Blockly.Msg.CALL_PROC_TITLE)
.appendField(
new Blockly.FieldImage(
ocargo.Drawing.imageDir + "empty.svg",
@@ -309,7 +309,7 @@ function initCustomBlocksDescription() {
.appendField(new Blockly.FieldTextInput(name), "NAME");
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Call"));
+ this.setTooltip(Blockly.Msg.CALL_PROC_TOOLTIP);
},
};
@@ -319,12 +319,12 @@ function initCustomBlocksDescription() {
var name = "";
this.setColour(260);
this.appendDummyInput()
- .appendField(gettext("Define"))
+ .appendField(Blockly.Msg.DECLARE_PROC_TITLE)
.appendField(new Blockly.FieldTextInput(name), "NAME");
this.appendStatementInput("DO")
.setCheck("Action")
.appendField(gettext("Do"));
- this.setTooltip(gettext("Declares the procedure"));
+ this.setTooltip(Blockly.Msg.DECLARE_PROC_TOOLTIP);
this.statementConnection_ = null;
},
};
@@ -378,13 +378,13 @@ function initCustomBlocksDescription() {
this.setColour(120);
this.appendValueInput("condition")
.setCheck("Boolean")
- .appendField(gettext("repeat while"));
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_WHILE_TITLE);
this.appendStatementInput("body")
.setCheck("Action")
- .appendField(gettext("do"));
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_WHILE_SUBTITLE);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("While a value is true, do some statements"));
+ this.setTooltip(Blockly.Msg.CONTROLS_REPEAT_WHILE_TOOLTIP);
},
};
@@ -394,13 +394,13 @@ function initCustomBlocksDescription() {
this.setColour(120);
this.appendValueInput("condition")
.setCheck("Boolean")
- .appendField(gettext("repeat until"));
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_UNTIL_TITLE);
this.appendStatementInput("body")
.setCheck("Action")
- .appendField(gettext("do"));
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_UNTIL_SUBTITLE);
this.setPreviousStatement(true, "Action");
this.setNextStatement(true, "Action");
- this.setTooltip(gettext("Until a value is true, do some statements"));
+ this.setTooltip(Blockly.Msg.CONTROLS_REPEAT_UNTIL_TOOLTIP);
},
};
@@ -416,7 +416,7 @@ function initCustomBlocksDescription() {
);
this.setOutput(true, null);
this.setColour(330);
- this.setTooltip(gettext("A variable"));
+ this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
},
};
@@ -424,41 +424,41 @@ function initCustomBlocksDescription() {
init: function () {
this.appendValueInput("VALUE")
.setCheck(null)
- .appendField("set")
+ .appendField(Blockly.Msg.VARIABLES_SET_TITLE)
.appendField(new Blockly.FieldTextInput(""), "VAR")
- .appendField("to");
+ .appendField(Blockly.Msg.VARIABLES_SET_SUBTITLE);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(330);
- this.setTooltip(gettext("Set a variable"));
+ this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
},
};
Blockly.Blocks["variables_numeric_set"] = {
init: function () {
this.appendDummyInput()
- .appendField("set")
+ .appendField(Blockly.Msg.VARIABLES_SET_TITLE)
.appendField(new Blockly.FieldTextInput(""), "NAME")
- .appendField("to")
+ .appendField(Blockly.Msg.VARIABLES_SET_SUBTITLE)
.appendField(new Blockly.FieldNumber(0), "VALUE");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(330);
- this.setTooltip(gettext("Set a variable to a number"));
+ this.setTooltip(Blockly.Msg.VARIABLES_NUMERIC_SET_TOOLTIP);
},
};
Blockly.Blocks["variables_increment"] = {
init: function () {
this.appendDummyInput()
- .appendField("increment")
+ .appendField(Blockly.Msg.VARIABLES_INCREMENT_TITLE)
.appendField(new Blockly.FieldTextInput(""), "NAME")
- .appendField("by")
+ .appendField(Blockly.Msg.VARIABLES_INCREMENT_SUBTITLE)
.appendField(new Blockly.FieldNumber(0), "VALUE");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(330);
- this.setTooltip(gettext("Increment a variable"));
+ this.setTooltip(Blockly.Msg.VARIABLES_INCREMENT_TOOLTIP);
},
};
@@ -469,11 +469,11 @@ function initCustomBlocksDescription() {
Blockly.Blocks["math_number"] = {
init: function () {
this.appendDummyInput()
- .appendField("number")
+ .appendField(Blockly.Msg.NUMBER_TITLE)
.appendField(new Blockly.FieldNumber(0), "NUM");
this.setOutput(true, null);
this.setColour(230);
- this.setTooltip(gettext("A number"));
+ this.setTooltip(Blockly.Msg.NUMBER_TOOLTIP);
},
};
diff --git a/game/static/game/js/blocklyCustomisations.js b/game/static/game/js/blocklyCustomisations.js
index bd9ba5979..355cce5c2 100644
--- a/game/static/game/js/blocklyCustomisations.js
+++ b/game/static/game/js/blocklyCustomisations.js
@@ -5,6 +5,7 @@ var ocargo = ocargo || {};
ocargo.BlocklyCustomisations = function () {
const TOOLBOX_REMAINING_CAPACITY_TEXT_COLUMN_WIDTH = 50;
+ const QUANTITY_TEXT_OFFSET = 35;
var limitedBlocks = false;
var blockCount = {};
@@ -94,6 +95,7 @@ ocargo.BlocklyCustomisations = function () {
flyoutWidth *= this.workspace_.scale;
flyoutWidth += Blockly.Scrollbar.scrollbarThickness;
flyoutWidth += TOOLBOX_REMAINING_CAPACITY_TEXT_COLUMN_WIDTH;
+ flyoutWidth += 50;
if (this.width_ != flyoutWidth) {
for (var i = 0, block; block = blocks[i]; i++) {
@@ -173,7 +175,7 @@ ocargo.BlocklyCustomisations = function () {
var attributes = {
'width': 30,
'height': 30,
- 'x': this.width_ - TOOLBOX_REMAINING_CAPACITY_TEXT_COLUMN_WIDTH,
+ 'x': blockHW.width + QUANTITY_TEXT_OFFSET,
'y': cursorY + 22,
'class': 'quantity_text',
'value': block.type
diff --git a/game/static/game/js/game.js b/game/static/game/js/game.js
index be1fae43e..28682e081 100644
--- a/game/static/game/js/game.js
+++ b/game/static/game/js/game.js
@@ -10,6 +10,8 @@ ocargo.Game = function () {
}
ocargo.Game.prototype.setup = function () {
+ gameUpdateBlockLanguage(navigator.language.toLowerCase())
+
if(new Date().getMonth() === 11) {
$("#paper").css('background-color', '#eef7ff')
}
@@ -25,11 +27,11 @@ ocargo.Game.prototype.setup = function () {
}
-// Function being called when there is a change in game level.
-ocargo.Game.prototype.onLevelChange = function() {
- const currentLevelId = LEVEL_ID;
- localStorage.setItem('currentEpisode', EPISODE);
-}
+ // Function being called when there is a change in game level.
+ ocargo.Game.prototype.onLevelChange = function() {
+ const currentLevelId = LEVEL_ID;
+ localStorage.setItem('currentEpisode', EPISODE);
+ }
restoreCmsLogin()
initCustomBlocks()
@@ -38,20 +40,21 @@ ocargo.Game.prototype.onLevelChange = function() {
ocargo.pythonControl = new ocargo.PythonControl()
ocargo.blocklyCompiler = new ocargo.BlocklyCompiler()
ocargo.model = new ocargo.Model(
- PATH,
- ORIGIN,
- DESTINATIONS,
- TRAFFIC_LIGHTS,
- COWS,
- MAX_FUEL
+ PATH,
+ ORIGIN,
+ DESTINATIONS,
+ TRAFFIC_LIGHTS,
+ COWS,
+ MAX_FUEL
)
+
this.drawing = new ocargo.Drawing(ocargo.model.startingPosition())
this.drawing.preloadRoadTiles()
ocargo.animation = new ocargo.Animation(ocargo.model, DECOR, this.drawing)
this.saving = new ocargo.Saving()
this.sharing = new ocargo.Sharing(
- () => parseInt(LEVEL_ID),
- () => true
+ () => parseInt(LEVEL_ID),
+ () => true
)
// Setup the blockly workspace
@@ -79,20 +82,20 @@ ocargo.Game.prototype.onLevelChange = function() {
// Setup blockly to python
Blockly.Python.init(Blockly.getMainWorkspace())
window.addEventListener(
- 'unload',
- function (event) {
- ocargo.pythonControl.teardown()
- ocargo.blocklyControl.teardown()
- }.bind(this)
+ 'unload',
+ function (event) {
+ ocargo.pythonControl.teardown()
+ ocargo.blocklyControl.teardown()
+ }.bind(this)
)
var loggedOutWarning = ''
// Check if logged on
if (USER_STATUS == 'UNTRACKED') {
loggedOutWarning =
- '
' +
- gettext("You are not logged in. Your progress won't be saved.") +
- ''
+ '
' +
+ gettext("You are not logged in. Your progress won't be saved.") +
+ ''
}
// Start the popup
var title = gettext('Try solving this one...')
@@ -113,11 +116,11 @@ ocargo.Game.prototype.onLevelChange = function() {
var message
if (NIGHT_MODE) {
message =
- '
' +
- gettext(
- 'In Night Mode you can only see a very short distance. ' +
- "We've given you more blocks to help you find your way!"
- )
+ '
' +
+ gettext(
+ 'In Night Mode you can only see a very short distance. ' +
+ "We've given you more blocks to help you find your way!"
+ )
} else {
message = loggedOutWarning
}
@@ -127,15 +130,15 @@ ocargo.Game.prototype.onLevelChange = function() {
const showMascot = BLOCKLY_ENABLED && !PYTHON_VIEW_ENABLED && LEVEL_NAME <= 80; // show mascot on Blockly-only levels that are not above 80
ocargo.Drawing.startPopup(
- title,
- LESSON,
- message,
- showMascot,
- [
- ocargo.button.dismissButtonHtml("prev_button", gettext("Previous level")),
- ocargo.button.dismissButtonHtml('play_button', gettext('Play')),
- ocargo.button.dismissButtonHtml("next_button", gettext("Next level"))
- ]
+ title,
+ LESSON,
+ message,
+ showMascot,
+ [
+ ocargo.button.dismissButtonHtml("prev_button", gettext("Previous level")),
+ ocargo.button.dismissButtonHtml('play_button', gettext('Play')),
+ ocargo.button.dismissButtonHtml("next_button", gettext("Next level"))
+ ]
)
}
@@ -624,6 +627,7 @@ ocargo.Game.prototype.isInPythonWorkspace = function () {
ocargo.Game.prototype._setupTabs = function () {
this.tabs = []
+
this.tabs.blockly = new ocargo.Tab(
$('#blockly_radio'),
$('#blockly_radio + label'),
@@ -1387,6 +1391,12 @@ function setMutedCookie(mute) {
}
}
+function gameUpdateBlockLanguage(language_code) {
+ loadLanguage("/static/game/js/blockly/msg/js/", language_code, function() {
+ reloadWorkspace(Blockly.mainWorkspace);
+ });
+}
+
$(document).ready(function () {
ocargo.game = new ocargo.Game()
ocargo.game.setup()
diff --git a/game/static/game/js/loadLanguages.js b/game/static/game/js/loadLanguages.js
new file mode 100644
index 000000000..9fa0577f5
--- /dev/null
+++ b/game/static/game/js/loadLanguages.js
@@ -0,0 +1,21 @@
+function loadLanguage(path, langStr, callback) {
+ var xobj = new XMLHttpRequest();
+ xobj.overrideMimeType("application/javascript");
+ xobj.open('GET', path + langStr + '.js', true);
+ xobj.onreadystatechange = function () {
+ if (xobj.readyState == 4 && xobj.status == "200") {
+ eval(xobj.responseText);
+ callback();
+ } else if (xobj.status == "404") {
+ loadLanguage(path, "en", callback);
+ }
+ };
+ xobj.send(null);
+};
+
+function reloadWorkspace(workspace) {
+ var blocklyDom = Blockly.Xml.workspaceToDom(workspace);
+ workspace.clear();
+ Blockly.Xml.domToWorkspace(blocklyDom, workspace);
+ workspace.updateToolbox(BLOCKLY_XML);
+};
\ No newline at end of file
diff --git a/game/templates/game/game.html b/game/templates/game/game.html
index 72c6f2a5f..c4e8df780 100644
--- a/game/templates/game/game.html
+++ b/game/templates/game/game.html
@@ -104,6 +104,7 @@
+
@@ -143,6 +144,7 @@
{% block content %}
{{ block.super }}
+