diff --git a/db/db_init.sql b/db/db_init.sql
index 409333c..72e36c9 100644
--- a/db/db_init.sql
+++ b/db/db_init.sql
@@ -42,7 +42,7 @@ CREATE TABLE "game" (
CREATE TABLE "game_info" (
"id" SERIAL PRIMARY KEY,
"time_control" varchar,
- "url" varchar
+ "chess_com_id" varchar
);
@@ -357,137 +357,137 @@ INSERT INTO "match" ("player1", "player2", "matchday") VALUES ( 9, 5, 26);
INSERT INTO "match" ("player1", "player2", "matchday") VALUES ( 7, 13, 26);
INSERT INTO "match" ("player1", "player2", "matchday") VALUES (14, 2, 26);
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8722014513');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8722014513'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8722014513');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8722014513'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8723231941');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8723231941'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8723231941');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8723231941'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8724907847');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8724907847'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8724907847');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8724907847'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8725036665');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8725036665'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8725036665');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8725036665'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8725614379');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8725614379'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8725614379');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8725614379'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8726184583');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8726184583'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8726184583');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8726184583'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8616485043');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8616485043'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8616485043');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8616485043'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8618149677');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8618149677'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8618149677');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8618149677'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8702757001');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8702757001'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8702757001');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8702757001'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8705204521');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8705204521'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8705204521');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8705204521'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8705796221');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8705796221'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8705796221');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8705796221'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8706438057');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8706438057'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8706438057');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8706438057'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8617630129');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8617630129'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8617630129');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8617630129'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8618225533');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8618225533'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8618225533');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8618225533'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8619306585');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8619306585'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8619306585');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8619306585'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8619471075');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8619471075'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8619471075');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8619471075'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8620078695');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8620078695'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8620078695');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8620078695'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8620568591');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8620568591'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8620568591');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8620568591'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8504667551');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 0, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8504667551'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8504667551');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 0, (SELECT id from game_info WHERE chess_com_id='8504667551'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8505882389');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8505882389'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8505882389');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8505882389'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8507004247');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8507004247'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8507004247');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8507004247'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8507617133');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8507617133'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8507617133');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8507617133'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8508203475');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8508203475'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8508203475');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8508203475'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8508297031');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8508297031'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8508297031');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8508297031'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8624735639');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8624735639'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8624735639');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8624735639'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8625353555');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8625353555'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8625353555');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8625353555'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8625963087');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8625963087'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8625963087');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8625963087'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8853361491');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8853361491'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8853361491');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8853361491'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8853455035');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8853455035'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8853455035');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8853455035'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8854002505');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8854002505'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8854002505');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8854002505'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8858219835');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8858219835'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8858219835');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8858219835'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8859375675');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8859375675'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8859375675');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8859375675'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8859976305');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8859976305'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8859976305');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8859976305'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8860591347');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8860591347'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8860591347');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8860591347'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8860675419');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8860675419'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8860675419');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8860675419'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8861228997');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8861228997'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8861228997');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8861228997'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8877523129');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8877523129'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8877523129');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8877523129'));
-INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8878652939');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8878652939'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('600', '8878652939');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8878652939'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8879853665');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8879853665'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8879853665');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE chess_com_id='8879853665'));
-INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8880469509');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8880469509'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('300', '8880469509');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE chess_com_id='8880469509'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8881562307');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8881562307'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8881562307');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE chess_com_id='8881562307'));
-INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8881610243');
-INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8881610243'));
+INSERT INTO "game_info" (time_control, chess_com_id) VALUES ('180', '8881610243');
+INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE chess_com_id='8881610243'));
diff --git a/frontend/app/views/main/main-view.css b/frontend/app/views/main/main-view.css
index a355ce4..43714e4 100644
--- a/frontend/app/views/main/main-view.css
+++ b/frontend/app/views/main/main-view.css
@@ -22,6 +22,14 @@
padding: var(--lumo-space-m);
}
+.bold-label {
+ font-weight: bold;
+}
+
+.nickname-label {
+ margin-left: var(--lumo-space-xs);
+}
+
/*//////////////////*/
/* APP-LAYOUT-STUFF */
/*//////////////////*/
diff --git a/frontend/app/views/match/match-view.css b/frontend/app/views/match/match-view.css
index e69de29..34af7f2 100644
--- a/frontend/app/views/match/match-view.css
+++ b/frontend/app/views/match/match-view.css
@@ -0,0 +1,62 @@
+.match-view .match-header-players {
+ width: 100%;
+ font-size: x-large;
+ justify-content: center;
+}
+
+.match-view .match-header-result {
+ width: 100%;
+ font-weight: bolder;
+ font-size: x-large;
+ text-align: center;
+}
+
+.match-view .game-card {
+ margin-top: var(--lumo-space-m);
+ margin-left: var(--lumo-space-m);
+}
+
+.match-view .player {
+ border-radius: var(--lumo-border-radius);
+ padding: var(--lumo-space-xs) 0;
+ width: 100%;
+ text-align: center;
+ align-content: center;
+}
+
+.match-view .black-player {
+ background-color: var(--lumo-shade);
+}
+
+.match-view .vs-label {
+ margin-top: 0;
+}
+
+.match-view .white-player {
+ margin-top: var(--lumo-space-xs);
+ margin-bottom: var(--lumo-space-m);
+ background-color: var(--lumo-tint);
+ color: var(--lumo-shade);
+}
+
+.match-view .game-info-div {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+.match-view .game-image-div {
+ min-width: 300px;
+ max-width: 300px;
+ min-height: 300px;
+ max-height: 300px;
+}
+
+.match-view .game-header {
+ font-weight: bolder;
+ font-size: large;
+ margin-bottom: var(--lumo-space-s);
+}
+
+.match-view .time-control {
+ margin-bottom: var(--lumo-space-s);
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 26bd1a5..2a4e3e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -126,12 +126,6 @@
3.0.0
-
-
-
-
-
-
com.h2database
h2
diff --git a/src/main/java/app/data/entity/GameInfo.java b/src/main/java/app/data/entity/GameInfo.java
index 48eecef..a9e30a3 100644
--- a/src/main/java/app/data/entity/GameInfo.java
+++ b/src/main/java/app/data/entity/GameInfo.java
@@ -7,7 +7,7 @@ import java.util.Objects;
@Table(name = "game_info", schema = "public", catalog = "chessleague")
public class GameInfo {
private Integer id;
- private String url;
+ private String chessComId;
private Game game;
private String timeControl;
@@ -23,13 +23,13 @@ public class GameInfo {
}
@Basic
- @Column(name = "url", length = -1)
- public String getUrl() {
- return url;
+ @Column(name = "chess_com_id", length = -1)
+ public String getChessComId() {
+ return chessComId;
}
- public void setUrl(String url) {
- this.url = url;
+ public void setChessComId(String chessComId) {
+ this.chessComId = chessComId;
}
@Basic
@@ -47,12 +47,12 @@ public class GameInfo {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GameInfo that = (GameInfo) o;
- return Objects.equals(id, that.id) && Objects.equals(url, that.url) && Objects.equals(timeControl, that.timeControl);
+ return Objects.equals(id, that.id) && Objects.equals(chessComId, that.chessComId) && Objects.equals(timeControl, that.timeControl);
}
@Override
public int hashCode() {
- return Objects.hash(id, url, timeControl);
+ return Objects.hash(id, chessComId, timeControl);
}
@OneToOne(mappedBy = "gameInfo")
diff --git a/src/main/java/app/data/entity/Match.java b/src/main/java/app/data/entity/Match.java
index 554ac12..a0c9862 100644
--- a/src/main/java/app/data/entity/Match.java
+++ b/src/main/java/app/data/entity/Match.java
@@ -75,9 +75,4 @@ public class Match {
public void setMatchday(Matchday matchday) {
this.matchday = matchday;
}
-
- @Override
- public String toString() {
- return String.format("%s-vs-%s", player1.getNickname().toLowerCase(), player2.getNickname().toLowerCase());
- }
}
diff --git a/src/main/java/app/data/entity/Matchday.java b/src/main/java/app/data/entity/Matchday.java
index f267f28..ab9bce5 100644
--- a/src/main/java/app/data/entity/Matchday.java
+++ b/src/main/java/app/data/entity/Matchday.java
@@ -64,9 +64,4 @@ public class Matchday {
public void setSeason(Season season) {
this.season = season;
}
-
- @Override
- public String toString() {
- return number.toString();
- }
}
diff --git a/src/main/java/app/data/entity/Player.java b/src/main/java/app/data/entity/Player.java
index 8669b90..5c184f4 100644
--- a/src/main/java/app/data/entity/Player.java
+++ b/src/main/java/app/data/entity/Player.java
@@ -86,8 +86,4 @@ public class Player {
this.playerInfo = playerInfo;
}
- @Override
- public String toString() {
- return name + " (" + nickname + ")";
- }
}
diff --git a/src/main/java/app/data/entity/Season.java b/src/main/java/app/data/entity/Season.java
index 0dad9b7..4ba0854 100644
--- a/src/main/java/app/data/entity/Season.java
+++ b/src/main/java/app/data/entity/Season.java
@@ -65,12 +65,4 @@ public class Season {
this.matchdays = matchdays;
}
- @Override
- public String toString() {
- String s = yearStart.toString();
- if (!yearEnd.equals(yearStart)) {
- s += "-" + yearEnd.toString();
- }
- return s;
- }
}
diff --git a/src/main/java/app/data/service/ChessComService.java b/src/main/java/app/data/service/ChessComService.java
index cc7ae48..ee10ec2 100644
--- a/src/main/java/app/data/service/ChessComService.java
+++ b/src/main/java/app/data/service/ChessComService.java
@@ -85,7 +85,7 @@ public class ChessComService {
game.setResult(ChessComUtils.getResult(chessComGame));
game.setGameInfo(gameInfo);
- gameInfo.setUrl(chessComGame.getUrl());
+ gameInfo.setChessComId(chessComGame.getUrl());
gameInfo.setTimeControl(chessComGame.getTimeControl());
gameInfo.setGame(game);
@@ -108,11 +108,12 @@ public class ChessComService {
}
List chessComGames = chessComArchive.get().getGames();
for (ChessComGame chessComGame : chessComGames) {
- if (chessComGame.getUrl().equals(game.getGameInfo().getUrl())) {
+ if (chessComGame.getUrl().equals(game.getGameInfo().getChessComId())) {
return Optional.of(chessComGame);
}
}
}
return Optional.empty();
}
+
}
diff --git a/src/main/java/app/data/service/MatchService.java b/src/main/java/app/data/service/MatchService.java
index f5ee09a..dec5155 100644
--- a/src/main/java/app/data/service/MatchService.java
+++ b/src/main/java/app/data/service/MatchService.java
@@ -43,10 +43,14 @@ public class MatchService extends CrudService {
public List getCalculatedMatches(Matchday matchday) {
return getMatches(matchday).stream()
- .map(match -> new CalculatedMatch(match, match.getPlayer1(), match.getPlayer2(), getScore1(match), getScore2(match)))
+ .map(this::getCalculatedMatch)
.collect(Collectors.toList());
}
+ public CalculatedMatch getCalculatedMatch(Match match) {
+ return new CalculatedMatch(match, match.getPlayer1(), match.getPlayer2(), getScore1(match), getScore2(match));
+ }
+
private static double getScore1(Match match) {
double score = 0;
for (Game game : match.getGames()) {
diff --git a/src/main/java/app/gameimage/service/GameImageService.java b/src/main/java/app/gameimage/GameImageService.java
similarity index 83%
rename from src/main/java/app/gameimage/service/GameImageService.java
rename to src/main/java/app/gameimage/GameImageService.java
index e0d466d..671e6e8 100644
--- a/src/main/java/app/gameimage/service/GameImageService.java
+++ b/src/main/java/app/gameimage/GameImageService.java
@@ -1,10 +1,8 @@
-package app.gameimage.service;
+package app.gameimage;
import app.data.chesscom.ChessComGame;
import app.data.entity.Game;
import app.data.service.ChessComService;
-import app.gameimage.GameImageGenerator;
-import app.gameimage.GameImageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -25,7 +23,7 @@ public class GameImageService {
}
public Optional getImagePath(Game game) {
- String path = GameImageUtils.IMAGE_DEST_PATH + getGameNumber(game) + GameImageUtils.EXTENSION;
+ String path = GameImageUtils.IMAGE_DEST_PATH_SERVER + getGameNumber(game) + GameImageUtils.EXTENSION;
File f = new File(path);
if(f.isFile()) {
return Optional.of(path);
@@ -40,7 +38,7 @@ public class GameImageService {
}
private String getGameNumber(Game game) {
- String[] url = game.getGameInfo().getUrl().split("/");
+ String[] url = game.getGameInfo().getChessComId().split("/");
return url[url.length -1];
}
diff --git a/src/main/java/app/gameimage/GameImageUtils.java b/src/main/java/app/gameimage/GameImageUtils.java
index dd7a6a7..586ba09 100644
--- a/src/main/java/app/gameimage/GameImageUtils.java
+++ b/src/main/java/app/gameimage/GameImageUtils.java
@@ -6,9 +6,11 @@ import java.io.File;
import java.io.IOException;
public class GameImageUtils {
- public static final String IMAGE_SOURCE_PATH = "src/main/resources/META-INF/resources/images/chess-sources/";
- public static final String IMAGE_DEST_PATH = "src/main/resources/META-INF/resources/images/games/";
+ public static final String IMAGE_PATH_CLIENT = "images/games/";
public static final String EXTENSION = ".png";
+
+ static final String IMAGE_SOURCE_PATH_SERVER = "src/main/resources/META-INF/resources/images/chess-sources/";
+ static final String IMAGE_DEST_PATH_SERVER = "src/main/resources/META-INF/resources/images/games/";
private static final String EXTENSION_WITHOUT_DOT = "png";
private GameImageUtils() {}
@@ -16,7 +18,7 @@ public class GameImageUtils {
public static BufferedImage readImage(String fileNameWithoutExtension) {
BufferedImage img = null;
try {
- String path = IMAGE_SOURCE_PATH + fileNameWithoutExtension + EXTENSION;
+ String path = IMAGE_SOURCE_PATH_SERVER + fileNameWithoutExtension + EXTENSION;
img = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
@@ -26,7 +28,7 @@ public class GameImageUtils {
public static void writeImage(BufferedImage img, String fileNameWithoutExtension) {
try {
- String path = IMAGE_DEST_PATH + fileNameWithoutExtension + EXTENSION;
+ String path = IMAGE_DEST_PATH_SERVER + fileNameWithoutExtension + EXTENSION;
File outputFile = new File(path);
ImageIO.write(img, EXTENSION_WITHOUT_DOT, outputFile);
} catch (IOException e) {
diff --git a/src/main/java/app/navigation/Navigation.java b/src/main/java/app/navigation/Navigation.java
index 6b23466..56f9b46 100644
--- a/src/main/java/app/navigation/Navigation.java
+++ b/src/main/java/app/navigation/Navigation.java
@@ -7,11 +7,12 @@ import app.data.entity.Season;
import app.data.service.MatchService;
import app.data.service.MatchdayService;
import app.data.service.SeasonService;
-import app.navigation.service.NavigationLevel;
-import com.vaadin.flow.component.AbstractField;
-import com.vaadin.flow.component.HasValue;
-import com.vaadin.flow.component.UI;
+import app.utils.EntityStringUtils;
+import com.vaadin.flow.component.*;
+import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.select.Select;
+import com.vaadin.flow.data.renderer.ComponentRenderer;
+import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.router.BeforeEvent;
import com.vaadin.flow.router.HasUrlParameter;
import com.vaadin.flow.router.WildcardParameter;
@@ -59,6 +60,10 @@ public class Navigation implements HasUrlParameter {
seasonSelect.addValueChangeListener(seasonSelectValueChangeListener());
matchdaySelect.addValueChangeListener(matchdaySelectValueChangeListener());
matchSelect.addValueChangeListener(matchSelectValueChangeListener());
+
+ seasonSelect.setItemLabelGenerator(EntityStringUtils::getSeasonString);
+ matchdaySelect.setItemLabelGenerator(EntityStringUtils::getMatchdayString);
+ matchSelect.setItemLabelGenerator(EntityStringUtils::getMatchString);
}
public void setRoute(String route) {
@@ -98,9 +103,12 @@ public class Navigation implements HasUrlParameter {
String seasonParam = null;
String matchdayParam = null;
String matchParam = null;
- if (seasonEnabled() && seasonSelect.getOptionalValue().isPresent()) seasonParam = seasonSelect.getValue().toString();
- if (matchdayEnabled() && matchdaySelect.getOptionalValue().isPresent()) matchdayParam = matchdaySelect.getValue().toString();
- if (matchEnabled() && matchSelect.getOptionalValue().isPresent()) matchParam = matchSelect.getValue().toString();
+ if (seasonEnabled() && seasonSelect.getOptionalValue().isPresent())
+ seasonParam = EntityStringUtils.getSeasonStringForURL(seasonSelect.getValue());
+ if (matchdayEnabled() && matchdaySelect.getOptionalValue().isPresent())
+ matchdayParam = EntityStringUtils.getMatchdayStringForURL(matchdaySelect.getValue());
+ if (matchEnabled() && matchSelect.getOptionalValue().isPresent())
+ matchParam = EntityStringUtils.getMatchStringForURL(matchSelect.getValue());
String params = NavigationUtils.getWildcardParam(seasonParam, matchdayParam, matchParam);
UI.getCurrent().getPage().getHistory().pushState(null, String.format("%s/%s", getRoute(), params));
@@ -197,54 +205,27 @@ public class Navigation implements HasUrlParameter {
@Override
public void setParameter(BeforeEvent event, @WildcardParameter String param) {
- Map> map = NavigationUtils.getParameterMap(param);
- navigate(map.get(UrlParameterType.SEASON), map.get(UrlParameterType.MATCHDAY), map.get(UrlParameterType.MATCH));
+ Map> map = NavigationUtils.getParameterMap(param);
+ navigate(map.get(NavigationLevel.SEASON), map.get(NavigationLevel.MATCHDAY), map.get(NavigationLevel.MATCH));
}
private void navigate(Optional seasonParam, Optional matchdayParam, Optional matchParam) {
if (!seasonEnabled()) return;
- Optional season = getSeasonFromParam(seasonParam);
+ Optional season = NavigationUtils.getObjectFromParam(seasonList, seasonParam);
if (season.isPresent()) seasonSelect.setValue(season.get());
else autoselectSeason();
if (!matchdayEnabled()) return;
- Optional matchday = getMatchdayFromParam(matchdayParam);
+ Optional matchday = NavigationUtils.getObjectFromParam(matchdayList, matchdayParam);
if (matchday.isPresent()) matchdaySelect.setValue(matchday.get());
else autoselectMatchday();
if (!matchEnabled()) return;
- Optional match = getMatchFromParam(matchParam);
+ Optional match = NavigationUtils.getObjectFromParam(matchList, matchParam);
if (match.isPresent()) matchSelect.setValue(match.get());
else autoselectMatch();
}
- private Optional getSeasonFromParam(Optional seasonParam) {
- if (seasonParam.isEmpty()) {
- return Optional.empty();
- }
- return seasonList.stream()
- .filter(season -> season.toString().equals(seasonParam.get()))
- .findFirst();
- }
-
- private Optional getMatchdayFromParam(Optional matchdayParam) {
- if (matchdayParam.isEmpty()) {
- return Optional.empty();
- }
- return matchdayList.stream()
- .filter(matchday -> matchday.toString().equals(matchdayParam.get()))
- .findFirst();
- }
-
- private Optional getMatchFromParam(Optional matchParam) {
- if (matchParam.isEmpty()) {
- return Optional.empty();
- }
- return matchList.stream()
- .filter(match -> match.toString().equals(matchParam.get()))
- .findFirst();
- }
-
public ValidationLabel getValidationLabel() {
return validationLabel;
}
diff --git a/src/main/java/app/navigation/service/NavigationLevel.java b/src/main/java/app/navigation/NavigationLevel.java
similarity index 71%
rename from src/main/java/app/navigation/service/NavigationLevel.java
rename to src/main/java/app/navigation/NavigationLevel.java
index 8f714b7..8dff644 100644
--- a/src/main/java/app/navigation/service/NavigationLevel.java
+++ b/src/main/java/app/navigation/NavigationLevel.java
@@ -1,4 +1,4 @@
-package app.navigation.service;
+package app.navigation;
public enum NavigationLevel {
NONE,
diff --git a/src/main/java/app/navigation/service/NavigationService.java b/src/main/java/app/navigation/NavigationService.java
similarity index 96%
rename from src/main/java/app/navigation/service/NavigationService.java
rename to src/main/java/app/navigation/NavigationService.java
index d26989c..885814b 100644
--- a/src/main/java/app/navigation/service/NavigationService.java
+++ b/src/main/java/app/navigation/NavigationService.java
@@ -1,4 +1,4 @@
-package app.navigation.service;
+package app.navigation;
import app.data.service.MatchService;
import app.data.service.MatchdayService;
diff --git a/src/main/java/app/navigation/NavigationUtils.java b/src/main/java/app/navigation/NavigationUtils.java
index e706123..c159b55 100644
--- a/src/main/java/app/navigation/NavigationUtils.java
+++ b/src/main/java/app/navigation/NavigationUtils.java
@@ -4,34 +4,38 @@ import com.vaadin.flow.router.WildcardParameter;
import org.springframework.lang.NonNull;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
-public class NavigationUtils {
+@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+class NavigationUtils {
+ private NavigationUtils() {
+ }
@NonNull
- public static Map> getParameterMap(@WildcardParameter String param) {
- Map> map = new HashMap<>();
+ static Map> getParameterMap(@WildcardParameter String param) {
+ Map> map = new HashMap<>();
String[] params = param.split("/");
switch (params.length) {
case 3:
- map.put(UrlParameterType.MATCH, Optional.of(params[2]));
+ map.put(NavigationLevel.MATCH, Optional.of(params[2]));
case 2:
- map.put(UrlParameterType.MATCHDAY, Optional.of(params[1]));
+ map.put(NavigationLevel.MATCHDAY, Optional.of(params[1]));
case 1:
- map.put(UrlParameterType.SEASON, Optional.of(params[0]));
+ map.put(NavigationLevel.SEASON, Optional.of(params[0]));
default:
break;
}
- map.putIfAbsent(UrlParameterType.MATCH, Optional.empty());
- map.putIfAbsent(UrlParameterType.MATCHDAY, Optional.empty());
- map.putIfAbsent(UrlParameterType.SEASON, Optional.empty());
+ map.putIfAbsent(NavigationLevel.MATCH, Optional.empty());
+ map.putIfAbsent(NavigationLevel.MATCHDAY, Optional.empty());
+ map.putIfAbsent(NavigationLevel.SEASON, Optional.empty());
return map;
}
@NonNull
- public static String getWildcardParam(String... params) {
+ static String getWildcardParam(String... params) {
StringBuilder stringBuilder = new StringBuilder();
for (String param : params) {
if (param == null || param.equals("")) {
@@ -41,4 +45,13 @@ public class NavigationUtils {
}
return stringBuilder.toString();
}
+
+ static Optional getObjectFromParam(List objectList, Optional param) {
+ if (param.isEmpty()) {
+ return Optional.empty();
+ }
+ return objectList.stream()
+ .filter(match -> match.toString().equals(param.get()))
+ .findFirst();
+ }
}
diff --git a/src/main/java/app/navigation/UrlParameterType.java b/src/main/java/app/navigation/UrlParameterType.java
deleted file mode 100644
index 9e74c9f..0000000
--- a/src/main/java/app/navigation/UrlParameterType.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package app.navigation;
-
-public enum UrlParameterType {
- SEASON,
- MATCHDAY,
- MATCH
-}
diff --git a/src/main/java/app/utils/ChessComUtils.java b/src/main/java/app/utils/ChessComUtils.java
index c1364de..64854fa 100644
--- a/src/main/java/app/utils/ChessComUtils.java
+++ b/src/main/java/app/utils/ChessComUtils.java
@@ -1,12 +1,17 @@
package app.utils;
import app.data.chesscom.ChessComGame;
+import app.data.entity.Game;
import app.data.entity.Match;
import app.data.entity.Player;
import org.springframework.lang.NonNull;
public class ChessComUtils {
- private ChessComUtils() {}
+
+ private static final String GAME_LINK = "https://www.chess.com/live/game/{gameId}";
+
+ private ChessComUtils() {
+ }
public static String getPreparedArchiveJson(String unpreparedArchiveJson) {
return unpreparedArchiveJson
@@ -46,4 +51,8 @@ public class ChessComUtils {
return false;
}
+ public static String getGameLink(Game game) {
+ String gameId = game.getGameInfo().getChessComId();
+ return GAME_LINK.replace("{gameId}", gameId);
+ }
}
diff --git a/src/main/java/app/utils/EntityComponentUtils.java b/src/main/java/app/utils/EntityComponentUtils.java
new file mode 100644
index 0000000..8b04c0b
--- /dev/null
+++ b/src/main/java/app/utils/EntityComponentUtils.java
@@ -0,0 +1,17 @@
+package app.utils;
+
+import app.data.entity.Player;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+
+public class EntityComponentUtils {
+ private EntityComponentUtils(){}
+
+ public static HorizontalLayout getPlayerLabel(Player player) {
+ Label name = new Label(player.getName());
+ name.addClassName("bold-label");
+ Label nickname = new Label(String.format("(%s)", player.getNickname()));
+ nickname.addClassName("nickname-label");
+ return new HorizontalLayout(name, nickname);
+ }
+}
diff --git a/src/main/java/app/utils/EntityStringUtils.java b/src/main/java/app/utils/EntityStringUtils.java
new file mode 100644
index 0000000..ecffa27
--- /dev/null
+++ b/src/main/java/app/utils/EntityStringUtils.java
@@ -0,0 +1,48 @@
+package app.utils;
+
+import app.data.entity.Match;
+import app.data.entity.Matchday;
+import app.data.entity.Player;
+import app.data.entity.Season;
+
+public class EntityStringUtils {
+ private EntityStringUtils() {
+ }
+
+ public static String getPlayerString(Player player) {
+ return String.format("%s (%s)", player.getName(), player.getNickname());
+ }
+
+ public static String getPlayerStringForURL(Player player) {
+ return player.getNickname().toLowerCase();
+ }
+
+ public static String getSeasonString(Season season) {
+ String string = season.getYearStart().toString();
+ if (!season.getYearEnd().equals(season.getYearStart())) {
+ string += "-" + season.getYearEnd().toString();
+ }
+ return string;
+ }
+
+ public static String getSeasonStringForURL(Season season) {
+ return getSeasonString(season);
+ }
+
+ public static String getMatchdayString(Matchday matchday ) {
+ return matchday.getNumber().toString();
+ }
+
+ public static String getMatchdayStringForURL(Matchday matchday) {
+ return matchday.getNumber().toString();
+ }
+
+ public static String getMatchString(Match match) {
+ return String.format("%s vs. %s", match.getPlayer1().getNickname(), match.getPlayer2().getNickname());
+ }
+
+ public static String getMatchStringForURL(Match match) {
+ return String.format("%s-vs-%s", match.getPlayer1().getNickname().toLowerCase(), match.getPlayer2().getNickname().toLowerCase());
+ }
+
+}
diff --git a/src/main/java/app/utils/StringUtils.java b/src/main/java/app/utils/StringUtils.java
index 49be410..0f3b8ce 100644
--- a/src/main/java/app/utils/StringUtils.java
+++ b/src/main/java/app/utils/StringUtils.java
@@ -9,15 +9,15 @@ public class StringUtils {
private StringUtils() {
}
- ////////////////
- // Formatting //
- ////////////////
+ ////////////////////////
+ // SPECIAL FORMATTING //
+ ////////////////////////
- public static String getResultString(Double first, Double second) {
+ public static String getResultString(String delimiter, Double first, Double second) {
String firstString = first.toString().replace(".0", "");
String secondString = second.toString().replace(".0", "");
- String result = firstString + " : " + secondString;
- if (result.equals("0 : 0")) {
+ String result = String.format("%s %s %s", firstString, delimiter, secondString);
+ if (result.equals("0 : 0")) { // TODO: care about delimiter
return "- : -";
}
return result;
@@ -41,7 +41,7 @@ public class StringUtils {
}
////////////////
- // Randomness //
+ // RANDOMNESS //
////////////////
private static final int RANDOM_STRING_LENGTH = 10;
diff --git a/src/main/java/app/views/match/MatchView.java b/src/main/java/app/views/match/MatchView.java
index 60880a7..0c0ca6b 100644
--- a/src/main/java/app/views/match/MatchView.java
+++ b/src/main/java/app/views/match/MatchView.java
@@ -1,9 +1,10 @@
package app.views.match;
import app.data.service.MatchService;
-import app.navigation.service.NavigationLevel;
-import app.navigation.service.NavigationService;
+import app.navigation.NavigationLevel;
+import app.navigation.NavigationService;
import app.views.main.MainView;
+import app.views.match.components.MatchComponent;
import app.views.navigation.NavigationViewBase;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.router.PageTitle;
@@ -17,6 +18,8 @@ public class MatchView extends NavigationViewBase {
private final MatchService matchService;
+ private MatchComponent matchComponent;
+
public MatchView(@Autowired NavigationService navigationService,
@Autowired MatchService matchService) {
super(navigationService, "match", NavigationLevel.MATCH);
@@ -32,6 +35,8 @@ public class MatchView extends NavigationViewBase {
////////////
private void configureLayout() {
+ matchComponent = new MatchComponent(navigation);
+ add(matchComponent);
}
/////////////
@@ -40,5 +45,6 @@ public class MatchView extends NavigationViewBase {
@Override
protected void configureContent() {
+ matchComponent.configureContent();
}
}
diff --git a/src/main/java/app/views/match/components/GameComponent.java b/src/main/java/app/views/match/components/GameComponent.java
new file mode 100644
index 0000000..214bb76
--- /dev/null
+++ b/src/main/java/app/views/match/components/GameComponent.java
@@ -0,0 +1,64 @@
+package app.views.match.components;
+
+import app.data.entity.Game;
+import app.views.match.components.utils.GameComponentUtils;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.html.Image;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.orderedlayout.FlexComponent;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+
+public class GameComponent extends Div {
+
+ private final Game game;
+
+ private final HorizontalLayout inner = new HorizontalLayout();
+
+ private final VerticalLayout left = new VerticalLayout();
+ private final Div right = new Div();
+
+ public GameComponent(Game game) {
+ this.game = game;
+
+ addClassName("wrapper");
+ addClassName("game-card");
+
+ configureInner();
+ }
+
+ private void configureInner() {
+ add(inner);
+ inner.add(left, right);
+ inner.setAlignItems(FlexComponent.Alignment.CENTER);
+
+ configureLeft();
+ configureRight();
+ }
+
+ private void configureLeft() {
+ Label header = GameComponentUtils.getHeader(game);
+ Div timeControlDiv = GameComponentUtils.getTimeControlDiv(game);
+ Div blackDiv = GameComponentUtils.getPlayerDiv(game, false);
+ Label vsLabel = GameComponentUtils.getVsLabel();
+ Div whiteDiv = GameComponentUtils.getPlayerDiv(game, true);
+ Button button = GameComponentUtils.getChessComButton(game);
+
+ left.add(header, timeControlDiv, blackDiv, vsLabel, whiteDiv, button);
+ left.addClassName("game-info-div");
+ left.setAlignItems(FlexComponent.Alignment.CENTER);
+
+ left.setHeightFull();
+
+ }
+
+ private void configureRight() {
+ right.addClassName("game-image-div");
+
+ Image image = new Image(GameComponentUtils.getImagePath(game), "Could not find game image.");
+ right.add(image);
+ image.setWidthFull();
+ image.setHeightFull();
+ }
+}
diff --git a/src/main/java/app/views/match/components/MatchComponent.java b/src/main/java/app/views/match/components/MatchComponent.java
new file mode 100644
index 0000000..36537e9
--- /dev/null
+++ b/src/main/java/app/views/match/components/MatchComponent.java
@@ -0,0 +1,82 @@
+package app.views.match.components;
+
+import app.data.bean.CalculatedMatch;
+import app.data.entity.Game;
+import app.data.entity.Match;
+import app.navigation.Navigation;
+import app.utils.EntityComponentUtils;
+import app.utils.StringUtils;
+import app.views.navigation.interfaces.ContentConfigurable;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.orderedlayout.FlexComponent;
+import com.vaadin.flow.component.orderedlayout.FlexLayout;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+
+import java.util.NoSuchElementException;
+
+public class MatchComponent extends Div implements ContentConfigurable {
+
+ private final Navigation navigation;
+
+ private final VerticalLayout headerLayout = new VerticalLayout();
+ private final HorizontalLayout headerPlayersLayout = new HorizontalLayout();
+ private final Label headerResultLabel = new Label();
+
+ private final FlexLayout gamesLayout = new FlexLayout();
+
+ public MatchComponent(Navigation navigation) {
+ this.navigation = navigation;
+
+ add(headerLayout, gamesLayout);
+
+ configureHeaderLayout();
+ configureGamesLayout();
+ }
+
+ private void configureHeaderLayout() {
+ headerLayout.add(headerPlayersLayout, headerResultLabel);
+
+ headerPlayersLayout.addClassName("match-header-players");
+
+ headerResultLabel.addClassName("match-header-result");
+ headerResultLabel.addClassName("bold-header");
+ }
+
+ private void configureGamesLayout() {
+ gamesLayout.setFlexWrap(FlexLayout.FlexWrap.WRAP);
+ gamesLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
+ }
+
+ @Override
+ public void configureContent() {
+ try {
+ Match match = navigation.getSelectedMatch().orElseThrow();
+
+ configureHeaderContent(match);
+
+ gamesLayout.removeAll();
+ for (Game game : match.getGames()) {
+ gamesLayout.add(new GameComponent(game));
+ }
+ } catch (NoSuchElementException e) {
+ gamesLayout.removeAll();
+ add(navigation.getValidationLabel());
+ }
+ }
+
+ private void configureHeaderContent(Match match) {
+ CalculatedMatch calculatedMatch = navigation.getMatchService().getCalculatedMatch(match);
+
+ HorizontalLayout player1 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer1());
+ HorizontalLayout player2 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer2());
+ Label vs = new Label("vs.");
+
+ headerPlayersLayout.removeAll();
+ headerPlayersLayout.add(player1, vs, player2);
+
+ headerResultLabel.setText(String.format("%s",
+ StringUtils.getResultString("-", calculatedMatch.getScore1(), calculatedMatch.getScore2())));
+ }
+}
diff --git a/src/main/java/app/views/match/components/utils/GameComponentUtils.java b/src/main/java/app/views/match/components/utils/GameComponentUtils.java
new file mode 100644
index 0000000..b91c3f8
--- /dev/null
+++ b/src/main/java/app/views/match/components/utils/GameComponentUtils.java
@@ -0,0 +1,151 @@
+package app.views.match.components.utils;
+
+import app.data.entity.Game;
+import app.data.entity.Player;
+import app.gameimage.GameImageUtils;
+import app.utils.ChessComUtils;
+import app.utils.EntityComponentUtils;
+import com.vaadin.flow.component.ClickEvent;
+import com.vaadin.flow.component.ComponentEventListener;
+import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.icon.Icon;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.FlexComponent;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class GameComponentUtils {
+ private GameComponentUtils() {
+ }
+
+ public static int getGameNumber(Game game) {
+ List games = new ArrayList<>(game.getMatch().getGames());
+ int index = games.indexOf(game);
+ if (index < 0) throw new IllegalStateException("The match associated with the Game does not contain the Game!");
+ return games.indexOf(game) + 1;
+ }
+
+ public static String getImagePath(Game game) {
+ String[] urlParts = game.getGameInfo().getChessComId().split("/");
+ return GameImageUtils.IMAGE_PATH_CLIENT + urlParts[urlParts.length - 1] + GameImageUtils.EXTENSION;
+ }
+
+ public static Player getWhitePlayer(Game game) {
+ return game.getPlayer1IsWhite() ? game.getMatch().getPlayer1() : game.getMatch().getPlayer2();
+ }
+
+ public static Player getBlackPlayer(Game game) {
+ return game.getPlayer1IsWhite() ? game.getMatch().getPlayer2() : game.getMatch().getPlayer1();
+ }
+
+ public static Div getPlayerDiv(Game game, boolean white) {
+ Player player = white ? getWhitePlayer(game) : getBlackPlayer(game);
+
+ Div div = new Div();
+ div.addClassName("player");
+ div.addClassName(white ? "white-player" : "black-player");
+
+ HorizontalLayout playerLabel = EntityComponentUtils.getPlayerLabel(player);
+ playerLabel.setWidthFull();
+ playerLabel.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
+
+ Label resultLabel = getResultLabel(game, white);
+ playerLabel.add(resultLabel);
+
+ div.add(playerLabel);
+
+ return div;
+ }
+
+ private static Label getResultLabel(Game game, boolean white) {
+ String resultString;
+ switch (game.getResult()) {
+ case -1:
+ resultString = white ? "0" : "1";
+ break;
+ case 0:
+ resultString = "0.5";
+ break;
+ case 1:
+ resultString = white ? "1" : "0";
+ break;
+ default:
+ throw new IllegalStateException(String.format("Game result must be either -1, 0, or 1, but it is %d!", game.getResult()));
+ }
+ Label resultLabel = new Label(resultString);
+ resultLabel.addClassName("bold-label");
+ return resultLabel;
+ }
+
+
+ public static Div getTimeControlDiv(Game game) {
+ String timeControl = game.getGameInfo().getTimeControl();
+
+ Icon icon;
+ String string;
+ switch (timeControl) {
+ case "600":
+ icon = new Icon(VaadinIcon.STOPWATCH);
+ string = "10 min";
+ break;
+ case "300":
+ icon = new Icon(VaadinIcon.BOLT);
+ string = "5 min";
+ break;
+ case "180":
+ icon = new Icon(VaadinIcon.BOMB);
+ string = "3 min";
+ break;
+ default:
+ icon = new Icon(VaadinIcon.QUESTION);
+ string = String.format("Unknown Time Control: %s", timeControl);
+ break;
+ }
+
+ Div div = new Div();
+ div.addClassName("time-control");
+
+ HorizontalLayout horizontalLayout = new HorizontalLayout();
+ horizontalLayout.setWidthFull();
+ horizontalLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
+ horizontalLayout.add(icon, new Label(string));
+
+ div.add(horizontalLayout);
+
+ return div;
+ }
+
+ public static Label getHeader(Game game) {
+ Label label = new Label();
+ label.setText(String.format("Game %d", getGameNumber(game)));
+ label.addClassName("game-header");
+ return label;
+ }
+
+ public static Button getChessComButton(Game game) {
+ String string = "Watch on Chess.com";
+ Icon icon = new Icon(VaadinIcon.EYE);
+
+ Button button = new Button(string, icon);
+ button.setWidthFull();
+ button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+
+ button.addClickListener(event ->
+ button.getUI().ifPresent(ui ->
+ ui.getPage().open(ChessComUtils.getGameLink(game), "_blank")));
+ return button;
+ }
+
+ public static Label getVsLabel() {
+ Label label = new Label("vs.");
+ label.addClassName("vs-label");
+ return label;
+ }
+}
diff --git a/src/main/java/app/views/matchday/MatchdayView.java b/src/main/java/app/views/matchday/MatchdayView.java
index 55190b7..881ccfd 100644
--- a/src/main/java/app/views/matchday/MatchdayView.java
+++ b/src/main/java/app/views/matchday/MatchdayView.java
@@ -1,7 +1,7 @@
package app.views.matchday;
-import app.navigation.service.NavigationLevel;
-import app.navigation.service.NavigationService;
+import app.navigation.NavigationLevel;
+import app.navigation.NavigationService;
import app.views.main.MainView;
import app.views.matchday.components.MatchdayComponent;
import app.views.navigation.NavigationViewBase;
diff --git a/src/main/java/app/views/matchday/components/MatchdayComponent.java b/src/main/java/app/views/matchday/components/MatchdayComponent.java
index c9d219e..f90ba20 100644
--- a/src/main/java/app/views/matchday/components/MatchdayComponent.java
+++ b/src/main/java/app/views/matchday/components/MatchdayComponent.java
@@ -5,6 +5,7 @@ import app.data.entity.Matchday;
import app.navigation.Navigation;
import app.navigation.components.button.NextMatchdayButton;
import app.navigation.components.button.PrevMatchdayButton;
+import app.utils.EntityStringUtils;
import app.utils.StringUtils;
import app.utils.VaadinUtils;
import app.views.navigation.interfaces.ContentConfigurable;
@@ -23,8 +24,6 @@ public class MatchdayComponent extends Div implements ContentConfigurable {
private final Navigation navigation;
- private final VerticalLayout inner = new VerticalLayout();
-
private final HorizontalLayout header = new HorizontalLayout();
private final Label headerLabel = new Label();
private final Grid grid = new Grid<>();
@@ -33,6 +32,7 @@ public class MatchdayComponent extends Div implements ContentConfigurable {
this.navigation = navigation;
addClassName("wrapper");
+ VerticalLayout inner = new VerticalLayout();
add(inner);
inner.add(header, grid);
@@ -79,14 +79,14 @@ public class MatchdayComponent extends Div implements ContentConfigurable {
}
private String getResultString(CalculatedMatch match) {
- return StringUtils.getResultString(match.getScore1(), match.getScore2());
+ return StringUtils.getResultString(":", match.getScore1(), match.getScore2());
}
@Override
public void configureContent() {
try {
Matchday matchday = navigation.getSelectedMatchday().orElseThrow();
- headerLabel.setText(String.format("Matchday %s", matchday.toString())); // TODO: add dates
+ headerLabel.setText(String.format("Matchday %s", EntityStringUtils.getMatchdayString(matchday))); // TODO: add dates
grid.setItems(navigation.getMatchService().getCalculatedMatches(matchday));
} catch (NoSuchElementException e) {
removeAll();
diff --git a/src/main/java/app/views/navigation/NavigationViewBase.java b/src/main/java/app/views/navigation/NavigationViewBase.java
index 410f0e8..a79b195 100644
--- a/src/main/java/app/views/navigation/NavigationViewBase.java
+++ b/src/main/java/app/views/navigation/NavigationViewBase.java
@@ -2,8 +2,8 @@ package app.views.navigation;
import app.navigation.Navigation;
import app.navigation.components.NavigationHeader;
-import app.navigation.service.NavigationLevel;
-import app.navigation.service.NavigationService;
+import app.navigation.NavigationLevel;
+import app.navigation.NavigationService;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEvent;
diff --git a/src/main/java/app/views/table/TableView.java b/src/main/java/app/views/table/TableView.java
index eeb0fa4..4af2419 100644
--- a/src/main/java/app/views/table/TableView.java
+++ b/src/main/java/app/views/table/TableView.java
@@ -1,8 +1,8 @@
package app.views.table;
import app.data.service.PlayerService;
-import app.navigation.service.NavigationLevel;
-import app.navigation.service.NavigationService;
+import app.navigation.NavigationLevel;
+import app.navigation.NavigationService;
import app.views.main.MainView;
import app.views.navigation.NavigationViewBase;
import app.views.table.components.TableComponent;
diff --git a/src/main/java/app/views/table/components/TableComponent.java b/src/main/java/app/views/table/components/TableComponent.java
index 28a1f91..447a255 100644
--- a/src/main/java/app/views/table/components/TableComponent.java
+++ b/src/main/java/app/views/table/components/TableComponent.java
@@ -113,7 +113,7 @@ public class TableComponent extends Div implements ContentConfigurable {
}
private String getResultString(PlayerForTable player) {
- return StringUtils.getResultString(player.getGamePointsForSelf(), player.getGamePointsForOpponents());
+ return StringUtils.getResultString(":", player.getGamePointsForSelf(), player.getGamePointsForOpponents());
}
@Override