Update some TODOs
[vchess.git] / public / javascripts / components / room.js
CommitLineData
b6487fb9
BA
1// TODO: main playing hall, chat + online players + current challenges + button "new game"
2/*
3input#modal-newgame.modal(type="checkbox")
4div(role="dialog" aria-labelledby="newGameTxt")
5 .card.smallpad.small-modal
6 label#close-newgame.modal-close(for="modal-newgame")
7 h3#newGameTxt= translations["New game"]
8 p= translations["Waiting for opponent..."]
9*/
10
2305d34a
BA
11// TODO: si on est en train de jouer une partie, le notifier aux nouveaux connectés
12
b6487fb9
BA
13/*
14Players + challenges : == "room" home of variant (surligner si nouveau défi perso et pas affichage courant)
15joueurs en ligne (dte),
16Nouvelle partie + défis en temps réel + parties en cours (milieu, tabs),
17chat général (gauche, activé ou non (bool global storage)).
18(cadences base + incrément, corr == incr >= 1jour ou base >= 7j)
19--> correspondance: stocker sur serveur lastMove + peerId + color + movesCount + gameId + variant + timeleft
20quand je poste un lastMove corr, supprimer mon ancien lastMove le cas échéant (tlm l'a eu)
21fin de partie corr: garder maxi nbPlayers lastMove sur serveur, pendant 7 jours (arbitraire)
22*/
81da2786
BA
23 case "newgame": //opponent found
24 // oppid: opponent socket ID
25 this.newGame("human", data.fen, data.color, data.oppid, data.gameid);
26 break;
27
28 // TODO: elsewhere, probably (new game button)
29 clickGameSeek: function(e) {
30 this.getRidOfTooltip(e.currentTarget);
31 if (this.mode == "human" && this.score == "*")
32 return; //no newgame while playing
33 if (this.seek)
34 {
35 this.conn.send(JSON.stringify({code:"cancelnewgame"}));
36 this.seek = false;
37 }
38 else
39 this.newGame("human");
40 },
41 clickComputerGame: function(e) {
42 this.getRidOfTooltip(e.currentTarget);
43 if (this.mode == "computer" && this.score == "*"
44 && this.vr.turn != this.mycolor)
45 {
46 // Wait for computer reply first (avoid potential "ghost move" bug)
47 return;
48 }
49 this.newGame("computer");
50 },
51 clickFriendGame: function(e) {
52 this.getRidOfTooltip(e.currentTarget);
53 document.getElementById("modal-fenedit").checked = true;
54 },
55 // In main hall :
56 newGame: function(mode, fenInit, color, oppId, gameId) {
57 const fen = fenInit || VariantRules.GenRandInitFen();
58 console.log(fen); //DEBUG
59 if (mode=="human" && !oppId)
60 {
61 const storageVariant = localStorage.getItem("variant");
8d7e2786 62 if (!!storageVariant && storageVariant !== variant.name
81da2786
BA
63 && localStorage["score"] == "*")
64 {
65 return alert(translations["Finish your "] +
66 storageVariant + translations[" game first!"]);
67 }
68 // Send game request and wait..
69 try {
70 this.conn.send(JSON.stringify({code:"newgame", fen:fen, gameid: getRandString() }));
71 } catch (INVALID_STATE_ERR) {
72 return; //nothing achieved
73 }
74 this.seek = true;
75 let modalBox = document.getElementById("modal-newgame");
76 modalBox.checked = true;
77 setTimeout(() => { modalBox.checked = false; }, 2000);
78 return;
79 }
80 const prefix = this.getStoragePrefix(mode);
81 if (mode == "computer")
82 {
83 const storageVariant = localStorage.getItem(prefix+"variant");
84 if (!!storageVariant)
85 {
86 const score = localStorage.getItem(prefix+"score");
8d7e2786 87 if (storageVariant !== variant.name && score == "*")
81da2786
BA
88 {
89 if (!confirm(storageVariant +
90 translations[": unfinished computer game will be erased"]))
91 {
92 return;
93 }
94 }
95 }
96 }
97 else if (mode == "friend")
98 {
99 const storageVariant = localStorage.getItem(prefix+"variant");
100 if (!!storageVariant)
101 {
102 const score = localStorage.getItem(prefix+"score");
8d7e2786 103 if (storageVariant !== variant.name && score == "*")
81da2786
BA
104 {
105 if (!confirm(storageVariant +
106 translations[": current analysis will be erased"]))
107 {
108 return;
109 }
110 }
111 }
112 }
113 this.vr = new VariantRules(fen, []);
114 this.score = "*";
115 this.pgnTxt = ""; //redundant with this.score = "*", but cleaner
116 this.mode = mode;
117 this.incheck = [];
118 this.fenStart = V.ParseFen(fen).position; //this is enough
119 if (mode=="human")
120 {
121 // Opponent found!
122 this.gameId = gameId;
123 this.oppid = oppId;
124 this.oppConnected = true;
125 this.mycolor = color;
126 this.seek = false;
127 if (this.sound >= 1)
128 new Audio("/sounds/newgame.mp3").play().catch(err => {});
129 document.getElementById("modal-newgame").checked = false;
130 }
131 else if (mode == "computer")
132 {
133 this.compWorker.postMessage(["init",this.vr.getFen()]);
134 this.mycolor = (Math.random() < 0.5 ? 'w' : 'b');
135 if (this.mycolor != this.vr.turn)
136 this.playComputerMove();
137 }
138 else if (mode == "friend")
139 this.mycolor = "w"; //convention...
140 //else: problem solving: nothing more to do
141 if (mode != "problem")
142 this.setStorage(); //store game state in case of interruptions
143 },
144 continueGame: function(mode) {
145 this.mode = mode;
146 this.oppid = (mode=="human" ? localStorage.getItem("oppid") : undefined);
147 const prefix = this.getStoragePrefix(mode);
148 this.mycolor = localStorage.getItem(prefix+"mycolor");
149 const moves = JSON.parse(localStorage.getItem(prefix+"moves"));
150 const fen = localStorage.getItem(prefix+"fen");
151 const score = localStorage.getItem(prefix+"score"); //set in "endGame()"
152 this.fenStart = localStorage.getItem(prefix+"fenStart");
153 this.vr = new VariantRules(fen, moves);
154 this.incheck = this.vr.getCheckSquares(this.vr.turn);
155 if (mode == "human")
156 {
157 this.gameId = localStorage.getItem("gameId");
158 // Send ping to server (answer pong if opponent is connected)
159 this.conn.send(JSON.stringify({
160 code:"ping",oppid:this.oppid,gameId:this.gameId}));
161 }
162 else if (mode == "computer")
163 {
164 this.compWorker.postMessage(["init",fen]);
165 if (score == "*" && this.mycolor != this.vr.turn)
166 this.playComputerMove();
167 }
168 //else: nothing special to do in friend mode
169 if (score != "*")
170 {
171 // Small delay required when continuation run faster than drawing page
172 setTimeout(() => this.endGame(score), 100);
173 }
174 },
175
176
177 // TODO: option du bouton "new game"
178 const modalFenEdit = [
179 h('input',
180 {
181 attrs: { "id": "modal-fenedit", type: "checkbox" },
182 "class": { "modal": true },
183 }),
184 h('div',
185 {
186 attrs: { "role": "dialog", "aria-labelledby": "titleFenedit" },
187 },
188 [
189 h('div',
190 {
191 "class": { "card": true, "smallpad": true },
192 },
193 [
194 h('label',
195 {
196 attrs: { "id": "close-fenedit", "for": "modal-fenedit" },
197 "class": { "modal-close": true },
198 }
199 ),
200 h('h3',
201 {
202 attrs: { "id": "titleFenedit" },
203 "class": { "section": true },
204 domProps: { innerHTML: translations["Game state (FEN):"] },
205 }
206 ),
207 h('input',
208 {
209 attrs: {
210 "id": "input-fen",
211 type: "text",
212 value: VariantRules.GenRandInitFen(),
213 },
214 }
215 ),
216 h('button',
217 {
218 on: { click:
219 () => {
220 const fen = document.getElementById("input-fen").value;
221 document.getElementById("modal-fenedit").checked = false;
222 this.newGame("friend", fen);
223 }
224 },
225 domProps: { innerHTML: translations["Ok"] },
226 }
227 ),
228 h('button',
229 {
230 on: { click:
231 () => {
232 document.getElementById("input-fen").value =
233 VariantRules.GenRandInitFen();
234 }
235 },
236 domProps: { innerHTML: translations["Random"] },
237 }
238 ),
239 ]
240 )
241 ]
242 )
243 ];
244 elementArray = elementArray.concat(modalFenEdit);