Add polyfill to submit form on blur in safari
[brackets.git] / frontend / index.js
CommitLineData
98344134
JC
1const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
2
01952c94
JC
3/**
4 * Safari iOS pls
5 */
6const formSubmitPolyfill = (form, callback) => {
7 if (form.requestSubmit) {
8 form.requestSubmit();
9 } else {
10 callback();
11 }
12}
13
98344134
JC
14const createGenreListWithClickEvent = (genreList, genres, callback) => {
15 genreList.append(...genres.map((genre) => {
16 const name = genre["name"];
17 const li = document.createElement("li");
18 li.setAttribute("data-name", name);
19 li.addEventListener("click", callback);
20 li.appendChild(document.createTextNode(name));
21 return li;
22 }));
23}
24
25const relativeToCtx = (x1, x2, y1, y2, ctx) => {
26 const newX = x1 + x2;
27 const newY = y1 + y2;
28 ctx.lineTo(newX, newY);
29 return [newX, newY];
30}
31
1ffe1db0
JC
32/**
33 * Return (x,y) of canvas
34 */
35const getDimensions = (canvas) => [canvas.width, canvas.height];
36
37/**
38 * Return (x,y) midpoint of canvas
39 */
40const getCenter = (canvas) => getDimensions(canvas).map((dim) => dim / 2);
41
42/**
43 * Draw champion box and clear background.
44 */
45const drawWinner = (canvas) => {
98344134 46 const ctx = canvas.getContext("2d");
1ffe1db0
JC
47 const [width, height] = getDimensions(canvas);
48 const [mid_x, mid_y] = getCenter(canvas);
98344134
JC
49 const rect_width = width * .5;
50 const rect_height = height * .1;
51 ctx.strokeRect(mid_x - rect_width / 2, mid_y - rect_height / 2, rect_width, rect_height);
52 ctx.clearRect(mid_x - rect_width / 2, mid_y - rect_height / 2, rect_width, rect_height);
1ffe1db0
JC
53}
54
55/**
56 * Draws a path in context from the current location to a point xDist * left, yDist * up away from it.
57 * @param ctx RenderingContext
58 * @param x, y float current location
59 * @param x, y float distance away
60 * @param up, left (-1|1) directions
61 * @return [newNodeX, newNodeY]
62 */
63const drawBranchFrom = (ctx, x, y, xDist, yDist, left, up) => {
64 const newX = x + (xDist * left)
65 const newY = y + (yDist * up)
66 ctx.lineTo(x, newY);
67 ctx.lineTo(newX, newY);
68 return [newX, newY];
69}
70
71const drawArtistOnCtx = (ctx, artistName, x, y) => ctx.strokeText(artistName, x, y);
72
73/**
74 * Draws paths to the terminal nodes of a round
75 * @param x, y the point representation of the start of the branch
76 */
581e4442 77const drawMatchup = (canvas, x, y, iter, left, artist1, artist2) => {
1ffe1db0
JC
78 const ctx = canvas.getContext("2d");
79 const [width, height] = getDimensions(canvas);
80
81 const drawBranchUp = (xDist, yDist) => drawBranchFrom(ctx, x, y, xDist, yDist, left, 1);
82 const drawBranchDown = (xDist, yDist) => drawBranchFrom(ctx, x, y, xDist, yDist, left, -1);
83 const drawArtist = (artistName, x, y) => drawArtistOnCtx(ctx, artistName, x, y);
98344134 84
98344134 85 ctx.beginPath();
1ffe1db0
JC
86 ctx.moveTo(x, y);
87 drawArtist(
581e4442 88 artist1["name"],
1ffe1db0
JC
89 ...drawBranchUp(width / iter, height / iter)
90 );
91 ctx.moveTo(x, y);
92 drawArtist(
581e4442 93 artist2["name"],
1ffe1db0
JC
94 ...drawBranchDown(width / iter, height / iter)
95 );
98344134
JC
96 ctx.stroke();
97}
98
581e4442 99const drawBracket = (canvas, artists) => {
1ffe1db0
JC
100 drawWinner(canvas);
101 const [mid_x, mid_y] = getCenter(canvas);
581e4442
JC
102 const groups = 4;
103 const rounds = Math.log2(artists.length / groups);
104 for (let group = 1; group <= groups; group++) {
105 for (let round = 0; round < rounds; round++) {
106 const matchup = [artists.shift(), artists.pop()];
107 drawMatchup(canvas, mid_x, mid_y, 2 * round, Math.pow(-1, group), ...matchup);
108 }
109 }
1ffe1db0
JC
110}
111
98344134
JC
112window.onload = () => {
113 const lStorage = window.localStorage;
114 const genreList = document.getElementById("genre-list");
115 const genreInput = document.getElementById("genre-input");
116 const genreForm = document.getElementById("genre-form");
117 const canvas = document.getElementById("bracket");
118
01952c94
JC
119 const formSubmitAction = () => {
120 fetch(encodeURI(`http://localhost:8080/artist/genre?genre_name=${genreInput.value}`))
121 .then((response) => response.json())
122 .then((data) => drawBracket(canvas, data.slice(0, 33)));
123 }
124
98344134
JC
125 const createGenreList = (genreList, genres) => {
126 return createGenreListWithClickEvent(genreList, genres, (e) => {
127 genreInput.value = e.target.innerText;
01952c94 128 formSubmitPolyfill(genreForm, formSubmitAction);
98344134
JC
129 })
130 }
131 let genres = JSON.parse(lStorage.getItem("genres"))
132 if (genres === null) {
133 fetch("http://localhost:8080/genre")
134 .then((response) => response.text())
135 .then((text) => {
136 window.localStorage.setItem("genres", text);
137 genres = JSON.parse(text);
138 createGenreList(genreList, genres);
139 });
140 } else {
141 createGenreList(genreList, genres);
142 }
143
144 genreForm.addEventListener("submit", (e) => {
145 e.preventDefault();
01952c94 146 formSubmitAction()
98344134
JC
147 });
148
149 genreInput.addEventListener("input", (e) => {
150 const input = e.target;
6861bd5a 151 Array.from(genreList.children).forEach((item) => item.style.display= item.dataset.name.includes(input.value.toLowerCase()) ? "block" : "none");
98344134
JC
152 });
153 genreInput.addEventListener("focus", (e) => {
154 genreList.style.display = "block";
155 });
156 genreInput.addEventListener("blur", (e) => {
157 sleep(150).then(() => genreList.style.display = "none");
158 });
159
160
161 canvas.width = window.innerWidth;
162 canvas.height = window.innerHeight;
581e4442 163 drawBracket(canvas, []);
98344134
JC
164
165 const bgImg = new Image();
166 bgImg.onload = () => {
167 const ctx = canvas.getContext("2d");
168 //ctx.mozImageSmoothingEnabled = false;
169 //ctx.webkitImageSmoothingEnabled = false;
170 //ctx.msImageSmoothingEnabled = false;
171 //ctx.imageSmoothingEnabled = false;
172 ctx.drawImage(
173 bgImg,
174 0,
175 0,
176 (canvas.width / bgImg.width) * bgImg.width,
177 (canvas.height / bgImg.height) * bgImg.height
178 );
179 }
180
181 const upload = document.getElementById("image-upload");
182 upload.addEventListener("change", (e) => {
183 bgImg.src = URL.createObjectURL(e.target.files[0]);
184 });
185}