Skip to content

Commit 3068bb6

Browse files
author
Jay Ng
committed
feature(statement preview): load both EN/FR statements and allow switching in between
1 parent 3fba1a2 commit 3068bb6

File tree

4 files changed

+104
-54
lines changed

4 files changed

+104
-54
lines changed

runner/src/main/java/com/codingame/gameengine/runner/Renderer.java

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Enumeration;
2525
import java.util.HashSet;
2626
import java.util.List;
27+
import java.util.Optional;
2728
import java.util.Properties;
2829
import java.util.Set;
2930
import java.util.regex.Matcher;
@@ -50,6 +51,7 @@
5051
import com.google.gson.JsonArray;
5152
import com.google.gson.JsonElement;
5253
import com.google.gson.JsonIOException;
54+
import com.google.gson.JsonNull;
5355
import com.google.gson.JsonObject;
5456
import com.google.gson.JsonParser;
5557
import com.google.gson.JsonPrimitive;
@@ -700,45 +702,45 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
700702
exchange.setStatusCode(StatusCodes.NOT_FOUND);
701703
}
702704
} else if (exchange.getRelativePath().equals("/statement")) {
703-
File statementFileEN = sourceFolderPath.resolve("config/statement_en.html").toFile();
704-
File statementFileFR = sourceFolderPath.resolve("config/statement_fr.html").toFile();
705-
if (exchange.getRequestMethod().equalToString("POST")) {
706-
String statementEN = FileUtils.readFileToString(statementFileEN, StandardCharsets.UTF_8);
707-
String statementFR;
708-
if (!statementFileFR.exists()) {
709-
statementFR = "";
710-
} else {
711-
statementFR = FileUtils.readFileToString(statementFileFR, StandardCharsets.UTF_8);
712-
}
713-
714-
exchange.getRequestReceiver().receiveFullString((e, data) -> {
715-
if (data.equals("FR")) {
716-
exchange.getResponseSender().send(statementFR);
717-
} else {
718-
exchange.getResponseSender().send(statementEN);
719-
}
720-
}, StandardCharsets.UTF_8);
721-
} else if (exchange.getRequestMethod().equalToString("PUT")) {
722-
JsonParser parser = new JsonParser();
723-
exchange.getRequestReceiver().receiveFullString((e, data) -> {
724-
try {
725-
JsonObject result = parser.parse(data).getAsJsonObject();
726-
String language = result.get("language").getAsString();
727-
String statement = result.get("statement").getAsString();
728-
if (language.equals("FR")) {
729-
createFileIfNotExists(statementFileFR, e);
730-
FileUtils.write(statementFileFR, statement, StandardCharsets.UTF_8);
731-
} else if (language.equals("EN")) {
732-
FileUtils.write(statementFileEN, statement, StandardCharsets.UTF_8);
733-
}
734-
exchange.setStatusCode(StatusCodes.CREATED);
735-
} catch (IOException ex) {
736-
sendException(e, ex, StatusCodes.BAD_REQUEST);
737-
}
738-
}, StandardCharsets.UTF_8);
739-
} else {
740-
exchange.setStatusCode(StatusCodes.NOT_FOUND);
741-
}
705+
File statementFileEN = sourceFolderPath.resolve("config/statement_en.html").toFile();
706+
File statementFileFR = sourceFolderPath.resolve("config/statement_fr.html").toFile();
707+
if (exchange.getRequestMethod().equalToString("GET")) {
708+
JsonObject statements = new JsonObject();
709+
String statementEN = FileUtils.readFileToString(statementFileEN, StandardCharsets.UTF_8);
710+
String statementFR;
711+
if (!statementFileFR.exists()) {
712+
statementFR = null;
713+
} else {
714+
statementFR = FileUtils.readFileToString(statementFileFR, StandardCharsets.UTF_8);
715+
}
716+
JsonElement statementElement = toJsonElement(statementFR);
717+
statements.add("EN", new JsonPrimitive(statementEN));
718+
statements.add("FR", statementElement);
719+
exchange.getResponseSender().send(statements.toString());
720+
} else if (exchange.getRequestMethod().equalToString("PUT")) {
721+
JsonParser parser = new JsonParser();
722+
exchange.getRequestReceiver().receiveFullString((e, data) -> {
723+
try {
724+
JsonObject result = parser.parse(data).getAsJsonObject();
725+
String language = result.get("language").getAsString();
726+
String statement = result.get("statement").getAsString();
727+
if (language.equals("FR")) {
728+
if (!createFileIfNotExists(statementFileFR, e)) {
729+
// terminate if error in createFileIfNotExists
730+
return;
731+
}
732+
FileUtils.write(statementFileFR, statement, StandardCharsets.UTF_8);
733+
} else if (language.equals("EN")) {
734+
FileUtils.write(statementFileEN, statement, StandardCharsets.UTF_8);
735+
}
736+
exchange.setStatusCode(StatusCodes.CREATED);
737+
} catch (IOException ex) {
738+
sendException(e, ex, StatusCodes.BAD_REQUEST);
739+
}
740+
}, StandardCharsets.UTF_8);
741+
} else {
742+
exchange.setStatusCode(StatusCodes.NOT_FOUND);
743+
}
742744
}
743745
} catch (MissingConfigException e) {
744746
sendException(exchange, e, StatusCodes.UNPROCESSABLE_ENTITY);
@@ -749,14 +751,25 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
749751
}
750752
}
751753

752-
private void createFileIfNotExists(File statementFileFR, HttpServerExchange e) {
753-
if (!statementFileFR.exists()){
754-
try{
755-
statementFileFR.createNewFile();
754+
private JsonElement toJsonElement(String statementFR) {
755+
return Optional.ofNullable(statementFR)
756+
.map(s -> (JsonElement) new JsonPrimitive(s))
757+
.orElse(JsonNull.INSTANCE);
758+
}
759+
760+
private boolean createFileIfNotExists(File statementFileFR, HttpServerExchange e) {
761+
if (!statementFileFR.exists()) {
762+
try {
763+
statementFileFR.createNewFile();
764+
return true;
756765
} catch (IOException ex) {
757-
sendException(e, ex, StatusCodes.INTERNAL_SERVER_ERROR);
766+
sendException(e, ex, StatusCodes.INTERNAL_SERVER_ERROR);
767+
// only return false in case of error
768+
return false;
758769
}
759-
}
770+
} else {
771+
return true;
772+
}
760773
}
761774

762775
private JsonObject extractDemoFromGameJson(File gameFile) {

runner/src/main/resources/view/statement.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ button {
4444

4545
.tab-buttons button {
4646
height: 40px;
47+
outline: none;
4748
background-color: #ffffff;
4849
float: left;
4950
padding: 0px 16px;

runner/src/main/resources/view/statement.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<script src="statement.js"></script>
88
</head>
99

10-
<body onload="load()">
10+
<body onload="init()">
1111
<meta charset="UTF-8">
1212
<div class="wrapper">
1313

@@ -20,7 +20,7 @@
2020
<div class="edit">
2121
<div class="edit-title">HTML Source</div>
2222
<textarea id="statementInput" onkeyup="handleChangeStatementInput()" spellcheck="false"></textarea>
23-
<button id="save" onclick="save()" disabled>Saved</button>
23+
<button id="save" onclick="save()">Save</button>
2424
</div>
2525

2626
<div class="preview">

runner/src/main/resources/view/statement.js

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
var language = 'EN'
2+
var statements
3+
var saved = {
4+
EN: false,
5+
FR: false
6+
}
7+
var isDirty = {
8+
EN: false,
9+
FR: false
10+
}
211

312
function getStatementInput () {
413
return document.getElementById('statementInput').value
@@ -19,13 +28,24 @@ function refreshStatement () {
1928
}
2029
}
2130

22-
async function load () {
31+
async function init () {
2332
const response = await fetch('/services/statement', {
24-
method: 'POST',
25-
body: language
33+
method: 'GET'
2634
})
27-
const statement = await response.text()
28-
document.getElementById('statementInput').value = statement
35+
statements = JSON.parse(await response.text())
36+
loadStatement()
37+
38+
window.onbeforeunload = function (e) {
39+
if (!isDirty.EN && !isDirty.FR) {
40+
return null
41+
} else {
42+
return 'If you leave before saving, your changes will be lost.'
43+
}
44+
}
45+
}
46+
47+
function loadStatement () {
48+
document.getElementById('statementInput').value = statements[language]
2949
refreshStatement()
3050
}
3151

@@ -38,20 +58,36 @@ async function save () {
3858
statement: getStatementInput()
3959
})
4060
})
41-
document.getElementById('save').innerText = 'Saved'
61+
document.getElementById('save').innerText = 'Saved ' + language
62+
saved[language] = true
63+
isDirty[language] = false
4264
}
4365

4466
function handleChangeStatementInput () {
4567
document.getElementById('save').disabled = false
4668
document.getElementById('save').innerText = 'Save'
4769
refreshStatement()
70+
saved[language] = false
71+
isDirty[language] = true
72+
}
73+
74+
function updateSaveButton () {
75+
if (saved[language]) {
76+
document.getElementById('save').disabled = true
77+
document.getElementById('save').innerText = 'Saved ' + language
78+
} else {
79+
document.getElementById('save').disabled = false
80+
document.getElementById('save').innerText = 'Save'
81+
}
4882
}
4983

5084
function changeLanguage (event, tabLanguage) {
5185
for (const child of document.getElementById('tab-buttons').childNodes) {
5286
child.className = ''
5387
}
5488
event.currentTarget.className += ' active'
89+
statements[language] = document.getElementById('statementInput').value
5590
language = tabLanguage
56-
load()
91+
loadStatement()
92+
updateSaveButton()
5793
}

0 commit comments

Comments
 (0)