1 import { extractTime
} from "@/utils/timeControl";
3 // TODO: show game structure
5 // { gameId: "", players: [], timeControl: "", clocks: [] }
8 function dbOperation(callback
)
11 let DBOpenRequest
= window
.indexedDB
.open("vchess", 4);
13 DBOpenRequest
.onerror = function(event
) {
14 alert("Database error: " + event
.target
.errorCode
);
17 DBOpenRequest
.onsuccess = function(event
) {
18 db
= DBOpenRequest
.result
;
23 DBOpenRequest
.onupgradeneeded = function(event
) {
24 let db
= event
.target
.result
;
25 db
.onerror = function(event
) {
26 alert("Error while loading database: " + event
.target
.errorCode
);
28 // Create objectStore for vchess->games
29 db
.createObjectStore("games", { keyPath: "gameId" });
33 // Optional callback to get error status
34 function addGame(game
, callback
)
37 let transaction
= db
.transaction(["games"], "readwrite");
40 transaction
.oncomplete = function() {
41 callback({}); //everything's fine
43 transaction
.onerror = function() {
44 callback({errmsg: "addGame failed: " + transaction
.error
});
47 let objectStore
= transaction
.objectStore("games");
48 objectStore
.add(game
);
52 // Clear current live game from localStorage
54 localStorage
.deleteItem("gameInfo");
55 localStorage
.deleteItem("gameState");
61 return Object
.assign({},
62 JSON
.parse(localStorage
.getItem("gameInfo")),
63 JSON
.parse(localStorage
.getItem("gameState")));
66 // Only called internally after a score update
67 function transferToDb()
69 addGame(getCurrent(), (err
) => {
76 export const GameStorage
=
81 // Extract times (in [milli]seconds), set clocks, store in localStorage
82 const tc
= extractTime(o
.timeControl
);
84 // game infos: constant
91 timeControl: o
.timeControl
,
92 increment: tc
.increment
,
93 mode: "live", //function for live games only
96 // game state: will be updated
101 clocks: [...Array(o
.players
.length
)].fill(tc
.mainTime
),
102 started: [...Array(o
.players
.length
)].fill(false),
106 localStorage
.setItem("gameInfo", JSON
.stringify(gameInfo
));
107 localStorage
.setItem("gameState", JSON
.stringify(gameState
));
111 // TODO: also option to takeback a move ?
112 // NOTE: for live games only (all on server for corr)
113 update: function(o
) //move, clock, initime, score, colorIdx
115 // TODO: finish this --> colorIdx must be computed before entering the function
116 let gameState
= JSON
.parse(localStorage
.getItem("gameState"));
119 // https://stackoverflow.com/a/38750895
120 const allowed
= ['appear', 'vanish', 'start', 'end'];
121 const filtered_move
= Object
.keys(o
.move)
122 .filter(key
=> allowed
.includes(key
))
123 .reduce((obj
, key
) => {
127 gameState
.moves
.push(filtered_move
);
128 gameState
.fen
= o
.move.fen
;
129 const colorIdx
= ["w","b","g","r"][o
.move.color
];
130 gameState
.clocks
[colorIdx
] = o
.move.clock
;
132 if (!!o
.initime
) //just a flag (true)
133 gameState
.initime
= Date
.now();
135 gameState
.score
= o
.score
;
136 localStorage
.setItem("gameState", JSON
.stringify(gameState
));
137 if (!!o
.score
&& o
.score
!= "*")
138 transferToDb(); //game is over
142 // Since DB requests are asynchronous, require a callback using the result
143 // TODO: option for remote retrieval (third arg, or just "gameRef")
144 getLocal: function(gameId
, callback
)
147 dbOperation((db
) => {
148 // TODO: if gameId is provided, limit search to gameId (just .get(gameId). ...)
149 let objectStore
= db
.transaction('games').objectStore('games');
150 objectStore
.openCursor().onsuccess = function(event
) {
151 var cursor
= event
.target
.result
;
152 // if there is still another cursor to go, keep runing this code
155 games
.push(cursor
.value
);
164 // Delete a game in indexedDB
165 remove: function(gameId
, callback
)
167 dbOperation((db
) => {
168 let transaction
= db
.transaction(["games"], "readwrite");
171 transaction
.oncomplete = function() {
172 callback({}); //everything's fine
174 transaction
.onerror = function() {
175 callback({errmsg: "deleteGame failed: " + transaction
.error
});
178 transaction
.objectStore("games").delete(gameId
);
182 // Retrieve any live game from its identifiers (remote or not, running or not)
183 // NOTE: need callback because result might be obtained asynchronously
184 get: function(gameRef
, callback
)
186 const gid
= gameRef
.id
;
187 const rid
= gameRef
.rid
; //may be blank
190 // TODO: send request to server which forward to user sid == rid,
191 // need to listen to "remote game" event in main hall ?
192 return callback({}); //means "the game will arrive later" (TODO...)
195 const gameInfoStr
= localStorage
.getItem("gameInfo");
198 const gameInfo
= JSON
.parse(gameInfoStr
);
199 if (gameInfo
.gameId
== gid
)
201 const gameState
= JSON
.parse(localStorage
.getItem("gameState"));
202 return callback(Object
.assign({}, gameInfo
, gameState
));
206 // Game is local and not running
207 GameStorage
.getLocal(gid
, callback
);