all repos — artbound-python @ 28ba21f6c7910ba167040c393f92b6166b3b9ee3

A client-server reimplementation of the administration panel for ArtBound.

artbound_python/static/script.js (view raw)

  1const BS_COL_WIDTH = 4,
  2	MAX_WIDTH = MAX_HEIGHT = 1000,
  3	WATERMARK_SRC = "/static/res/wm.png",
  4	WATERMARK_WIDTH = 325,
  5	WATERMARK_HEIGHT = 98,
  6
  7	WATERMARK = new Image(),
  8	date = new Date(),
  9	month_input = document.getElementById("month_input"),
 10	month_div = document.getElementById("month_div"),
 11	get_button = document.getElementById("get_button"),
 12	selectall_button = document.getElementById("selectall_button"),
 13	selectnone_button = document.getElementById("selectnone_button"),
 14	togglecolor_button = document.getElementById("togglecolor_button"),
 15	controls_div = document.getElementById("controls"),
 16	opacity_range = document.getElementById("opacity_range"),
 17	main_container_div = document.getElementById("main_container"),
 18	content_div = document.getElementById("content"),
 19	canvas_link = document.getElementById("canvas-download");
 20
 21let	fanarts = new Array(),
 22	watermark_invert = '';
 23
 24WATERMARK.src = WATERMARK_SRC;
 25month_input.value = `${date.getFullYear()}-${("0" + (date.getMonth() + 1)).slice(-2)}`;
 26
 27function addCanvasEvents(img, canvas, ctx){
 28	function abc(e) {
 29		if (e.button == 0) addWatermark(e, img, canvas, ctx);
 30	}
 31
 32	canvas.addEventListener('mousemove', abc);
 33	canvas.addEventListener('mousedown', function(e) {
 34		canvas.removeEventListener('mousemove', abc);
 35		canvas.addEventListener('mousedown', abc);
 36	});
 37}
 38
 39function getNewCardHtml(element) {
 40	element.div = document.createElement("div");
 41	element.canvas = document.createElement("canvas");
 42	const div1 = document.createElement("div"),
 43		div2 = document.createElement("div"),
 44		a = document.createElement("a"),
 45		div3 = document.createElement("div"),
 46		div4 = document.createElement("div"),
 47		button1 = document.createElement("button"),
 48		button2 = document.createElement("button"),
 49		button3 = document.createElement("button"),
 50		button4 = document.createElement("button"),
 51		button5 = document.createElement("button"),
 52		filename = `${('0' + element.index).slice(-2)} - ${element.name}.png`;
 53	
 54	element.div.className = `col-md-${BS_COL_WIDTH} entry${element.enabled == 0 ? " entry-disabled" : ""}`;
 55	element.div.id = `div-${element.id}`;
 56	element.div.setAttribute("data-index", element.index);
 57	div1.className = `card mb-${BS_COL_WIDTH} box-shadow my-card`;
 58	element.canvas.className = "card-img-top entry-img";
 59	element.canvas.id = element.id;
 60	element.canvas.setAttribute("data-name", element.name);
 61	element.canvas.setAttribute("data-content", element.content);
 62	element.canvas.setAttribute("data-filename", filename)
 63	div2.className = "card-body";
 64	a.className = "card-text";
 65	a.innerText = filename;
 66	a.title = "Clicca per copiare."
 67	a.addEventListener("click", function() { navigator.clipboard.writeText(a.innerText); }, false)
 68	div3.className = "d-flex justify-content-between align-items-center card-controls";
 69	div4.className = "btn-group";
 70
 71	button1.className = button2.className = button3.className = button4.className = button5.className = "btn btn-sm btn-outline-secondary";
 72	button1.innerText = "⬅️";
 73	button2.innerText = "*️⃣";
 74	button3.innerText = "🔄";
 75	button5.innerText = "➡️";
 76	button4.innerText = "💾";
 77	button1.addEventListener("click", function() { moveUpDown(element.id, -1); }, false);
 78	button2.addEventListener("click", function() { toggleEntry(element.id); }, false);
 79	button3.addEventListener("click", function() { reloadEntry(element.id); }, false);
 80	button4.addEventListener("click", function() { saveEntry(element.id); }, false);
 81	button5.addEventListener("click", function() { moveUpDown(element.id, 1); }, false);
 82
 83	div4.appendChild(button1);
 84	div4.appendChild(button2);
 85	div4.appendChild(button3);
 86	div4.appendChild(button4);
 87	div4.appendChild(button5);
 88	div3.appendChild(div4);
 89	div2.appendChild(a);
 90	div2.appendChild(div3);
 91	div1.appendChild(element.canvas);
 92	div1.appendChild(div2);
 93	element.div.appendChild(div1);
 94
 95	const ctx = element.canvas.getContext("2d");
 96
 97	element.image = new Image();
 98	element.image.addEventListener("load", () => {
 99		console.warn("loaded " + element.content);
100		setBaseImage(element.image, element.canvas, ctx);
101		addCanvasEvents(element.image, element.canvas, ctx);
102	});
103	console.warn("loading " + element.content);
104	element.image.src = element.content;
105
106	return element.div;
107}
108
109async function updateFanartList() {
110	main_container_div.hidden = false;
111	content_div.innerHTML = "";
112	get_button.disabled = false;
113	get_button.innerText = "Aggiungi";
114	
115	let i = 0;
116	for (fanart of fanarts) {
117		if(fanart.enabled){
118			i++;
119			fanart.index = i;
120			content_div.appendChild(getNewCardHtml(fanart));
121		}
122	}
123
124	for (fanart of fanarts) {
125		if(!fanart.enabled){
126			fanart.index = 0;
127			content_div.appendChild(getNewCardHtml(fanart));
128		}
129	}
130}
131
132function getFanart(id){
133	return fanarts.find(element => element.id == id)
134}
135
136function toggleEntry(id) {
137	entry = getFanart(id);
138	if (!entry) return;
139
140	entry.enabled = !entry.enabled;
141	updateFanartList()
142}
143
144function saveCanvas(canvas) {
145	canvas_link.href = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
146	canvas_link.setAttribute("download", canvas.getAttribute("data-filename"));
147	canvas_link.click()
148}
149
150function saveEntry(id) {
151	entry = getFanart(id);
152	if (!entry) return;
153	saveCanvas(entry.canvas)
154}
155
156function reloadEntry(id){
157	const fanart = getFanart(id);
158	if (!fanart) return;
159
160	const old_div = fanart.div;
161	content_div.replaceChild(getNewCardHtml(fanart), old_div);
162	old_div.remove();
163}
164
165function selectAllNone(toggle) {
166	fanarts.map(x => x.enabled = toggle)
167	updateFanartList()
168}
169
170function debugFn(){
171	fanarts = JSON.parse('[{"id":"1dE8L7w2DuOfQSJwf5oRjAeJ-VZfy5o-6","date":["03","08","2022"],"name":"Saro","content":"/static/res/wm.png","enabled":1,"index":1,"div":{}},{"id":"1ZO2poqaylmh7_FkEjRthozVXFpcP1Edx","date":["18","08","2022"],"name":"suchetto","content":"https://drive.google.com/uc?id=1ZO2poqaylmh7_FkEjRthozVXFpcP1Edx","enabled":1,"index":2,"div":{}},{"id":"1jkpZzqnQUdXv7QiW1khuwnSsdnjudBt-","date":["18","08","2022"],"name":"suca","content":"https://drive.google.com/uc?id=1clZbi1QzJQo_c7PGWx-nmLgfPhXqHdZR","enabled":1,"index":3,"div":{}}]');
172	controls_div.hidden = false;
173	updateOpacity();
174	updateFanartList();
175}
176
177function toggleColor() {
178	watermark_invert = watermark_invert == '' ? 'invert(1)' : '';
179	updateColorDisplay();
180}
181
182function updateColorDisplay() {
183	togglecolor_button.innerText = watermark_invert ? "⚫" : "⚪";
184}
185
186function addWatermark(event, img, c, ctx) {
187	setBaseImage(img, c, ctx);
188
189	const rect = c.getBoundingClientRect();
190	const x = (event.clientX - rect.left) * c.width / c.clientWidth;
191	const y = (event.clientY - rect.top) * c.height / c.clientHeight;
192
193	ctx.globalAlpha = opacity_range.value;
194	ctx.filter = watermark_invert;
195	ctx.drawImage(WATERMARK, x - (WATERMARK_WIDTH / 2), y - (WATERMARK_HEIGHT / 2), WATERMARK_WIDTH, WATERMARK_HEIGHT);
196}
197
198function updateOpacity() {
199	opacity_label.innerHTML = Math.round(opacity_range.value * 100) + '%';
200}
201
202function setBaseImage(img, c, ctx) {
203	const f = Math.min(MAX_WIDTH / img.width, MAX_HEIGHT / img.height);
204
205	const new_width = c.width = Math.ceil(img.width * f);
206	const new_height = c.height = Math.ceil(img.height * f)
207
208	ctx.imageSmoothingEnabled = (f < 1);
209	ctx.drawImage(img, 0, 0, new_width, new_height);
210}
211
212function moveUpDown(id, amount) {
213	const pos = fanarts.indexOf(fanarts.find(element => element.id == id));
214	const new_pos = pos + amount;
215
216	if (new_pos <= -1 || new_pos >= fanarts.length) {
217		return;
218	}
219
220	[fanarts[pos], fanarts[new_pos]] = [fanarts[new_pos], fanarts[pos]];
221
222	updateFanartList();
223}
224
225async function postData(url = "", data = {}, contentType = "application/x-www-form-urlencoded") {
226    // Default options are marked with *
227    const response = await fetch(url, { method: "POST", headers: { "Content-Type": contentType },
228      //redirect: "follow", // manual, *follow, error
229      //referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
230      body: JSON.stringify(data), // body data type must match "Content-Type" header
231    });
232    return response.json();
233}
234
235function getArtworks() {
236	get_button.disabled = true;
237	get_button.innerText = "…"
238    postData("/", { month: month_input.value }, "application/json").then((data) => {
239        console.log(data);
240        fanarts = fanarts.concat(data);
241        controls_div.hidden = false;
242	    updateOpacity();
243	    updateFanartList();
244    });
245}
246
247function saveAll() {
248	const response = confirm("Vuoi davvero scaricare tutte le fanart?");
249	if(response == false) return;
250	
251	fanarts.forEach((fanart) => {
252		if(fanart.enabled) {
253			saveCanvas(fanart.canvas)
254		}
255	})
256}