Finished. Now some last styling
[vchess.git] / client / src / utils / gameStorage.js
CommitLineData
967a2686
BA
1// Game object: {
2// // Static informations:
11667c79 3// id: string
967a2686
BA
4// vname: string,
5// fenStart: string,
6// players: array of sid+id+name,
7// timeControl: string,
8// increment: integer (seconds),
9// mode: string ("live" or "corr")
10// imported: boolean (optional, default false)
11// // Game (dynamic) state:
12// fen: string,
13// moves: array of Move objects,
14// clocks: array of integers,
809ba2aa 15// initime: array of integers (when clock start running),
967a2686
BA
16// score: string (several options; '*' == running),
17// }
18
fd7aea36
BA
19import { ajax } from "@/utils/ajax";
20
967a2686
BA
21function dbOperation(callback)
22{
23 let db = null;
24 let DBOpenRequest = window.indexedDB.open("vchess", 4);
25
26 DBOpenRequest.onerror = function(event) {
27 alert("Database error: " + event.target.errorCode);
28 };
29
30 DBOpenRequest.onsuccess = function(event) {
31 db = DBOpenRequest.result;
32 callback(db);
33 db.close();
34 };
35
36 DBOpenRequest.onupgradeneeded = function(event) {
37 let db = event.target.result;
38 db.onerror = function(event) {
39 alert("Error while loading database: " + event.target.errorCode);
40 };
41 // Create objectStore for vchess->games
11667c79 42 let objectStore = db.createObjectStore("games", { keyPath: "id" });
42c15a75 43 objectStore.createIndex("score", "score"); //to search by game result
967a2686
BA
44 }
45}
46
47export const GameStorage =
48{
49 // Optional callback to get error status
c0b27606 50 // TODO: this func called from Hall seems to not work now...
967a2686
BA
51 add: function(game, callback)
52 {
53 dbOperation((db) => {
54 let transaction = db.transaction("games", "readwrite");
55 if (callback)
56 {
57 transaction.oncomplete = function() {
58 callback({}); //everything's fine
59 }
60 transaction.onerror = function() {
61 callback({errmsg: "addGame failed: " + transaction.error});
62 };
63 }
64 let objectStore = transaction.objectStore("games");
65 objectStore.add(game);
66 });
67 },
68
69 // TODO: also option to takeback a move ?
dcd68c41
BA
70 // obj: chat, move, fen, clocks, score[Msg], initime, ...
71 update: function(gameId, obj)
967a2686 72 {
3d55deea
BA
73 if (Number.isInteger(gameId) || !isNaN(parseInt(gameId)))
74 {
75 // corr: only move, fen and score
76 ajax(
77 "/games",
78 "PUT",
79 {
80 gid: gameId,
81 newObj:
82 {
63ca2b89 83 chat: obj.chat,
f41ce580 84 move: obj.move, //may be undefined...
3d55deea
BA
85 fen: obj.fen,
86 score: obj.score,
dcd68c41 87 scoreMsg: obj.scoreMsg,
b7cbbda1 88 drawOffer: obj.drawOffer,
3d55deea
BA
89 }
90 }
91 );
92 }
93 else
94 {
95 // live
96 dbOperation((db) => {
97 let objectStore = db.transaction("games", "readwrite").objectStore("games");
98 objectStore.get(gameId).onsuccess = function(event) {
99 const game = event.target.result;
100 Object.keys(obj).forEach(k => {
101 if (k == "move")
102 game.moves.push(obj[k]);
103 else
104 game[k] = obj[k];
105 });
106 objectStore.put(game); //save updated data
107 }
108 });
109 }
967a2686
BA
110 },
111
fd7aea36
BA
112 // Retrieve all local games (running, completed, imported...)
113 getAll: function(callback)
967a2686
BA
114 {
115 dbOperation((db) => {
116 let objectStore = db.transaction('games').objectStore('games');
fd7aea36
BA
117 let games = [];
118 objectStore.openCursor().onsuccess = function(event) {
119 let cursor = event.target.result;
120 // if there is still another cursor to go, keep running this code
121 if (cursor)
122 {
123 games.push(cursor.value);
124 cursor.continue();
967a2686 125 }
fd7aea36
BA
126 else
127 callback(games);
967a2686 128 }
fd7aea36
BA
129 });
130 },
131
132 // Retrieve any game from its identifiers (locally or on server)
133 // NOTE: need callback because result is obtained asynchronously
134 get: function(gameId, callback)
135 {
136 // corr games identifiers are integers
137 if (Number.isInteger(gameId) || !isNaN(parseInt(gameId)))
138 {
139 ajax("/games", "GET", {gid:gameId}, res => {
92b82def
BA
140 let game = res.game;
141 game.moves.forEach(m => {
142 m.squares = JSON.parse(m.squares);
143 });
144 callback(game);
fd7aea36
BA
145 });
146 }
147 else //local game
148 {
149 dbOperation((db) => {
150 let objectStore = db.transaction('games').objectStore('games');
967a2686
BA
151 objectStore.get(gameId).onsuccess = function(event) {
152 callback(event.target.result);
153 }
fd7aea36
BA
154 });
155 }
967a2686
BA
156 },
157
42c15a75
BA
158 getCurrent: function(callback)
159 {
160 dbOperation((db) => {
161 let objectStore = db.transaction('games').objectStore('games');
162 objectStore.get("*").onsuccess = function(event) {
163 callback(event.target.result);
164 };
165 });
166 },
167
967a2686
BA
168 // Delete a game in indexedDB
169 remove: function(gameId, callback)
170 {
171 dbOperation((db) => {
172 let transaction = db.transaction(["games"], "readwrite");
173 if (callback)
174 {
175 transaction.oncomplete = function() {
176 callback({}); //everything's fine
177 }
178 transaction.onerror = function() {
179 callback({errmsg: "removeGame failed: " + transaction.error});
180 };
181 }
182 transaction.objectStore("games").delete(gameId);
183 });
184 },
185};