all repos — artbound-python @ 98162a99e80cffcf4fb4ae0e338545bf9e3d2df1

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	authorize_button = document.getElementById("authorize_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
 20let	fanarts = new Array(),
 21	watermark_invert = '';
 22
 23WATERMARK.src = WATERMARK_SRC;
 24month_input.value = `${date.getFullYear()}-${("0" + (date.getMonth() + 1)).slice(-2)}`;
 25
 26function addCanvasEvents(img, canvas, ctx){
 27	function abc(e) {
 28		if (e.button == 0) addWatermark(e, img, canvas, ctx);
 29	}
 30
 31	canvas.addEventListener('mousemove', abc);
 32	canvas.addEventListener('mousedown', function(e) {
 33		canvas.removeEventListener('mousemove', abc);
 34		canvas.addEventListener('mousedown', abc);
 35	});
 36}
 37
 38function getNewCardHtml(element) {
 39	element.div = document.createElement("div");
 40	element.canvas = document.createElement("canvas");
 41	const div1 = document.createElement("div"),
 42		div2 = document.createElement("div"),
 43		a = document.createElement("a"),
 44		div3 = document.createElement("div"),
 45		div4 = document.createElement("div"),
 46		button1 = document.createElement("button"),
 47		button2 = document.createElement("button"),
 48		button3 = document.createElement("button"),
 49		button4 = document.createElement("button");
 50	
 51	element.div.className = `col-md-${BS_COL_WIDTH} entry${element.enabled == 0 ? " entry-disabled" : ""}`;
 52	element.div.id = `div-${element.id}`;
 53	element.div.setAttribute("data-index", element.index);
 54	div1.className = `card mb-${BS_COL_WIDTH} box-shadow my-card`;
 55	element.canvas.className = "card-img-top entry-img";
 56	element.canvas.id = element.id;
 57	element.canvas.setAttribute("data-name", element.name);
 58	element.canvas.setAttribute("data-content", element.content);
 59	div2.className = "card-body";
 60	a.className = "card-text";
 61	a.innerText = `${('0' + element.index).slice(-2)} - ${element.name}.png`;
 62	a.title = "Clicca per copiare."
 63	a.addEventListener("click", function() { navigator.clipboard.writeText(a.innerText); }, false)
 64	div3.className = "d-flex justify-content-between align-items-center card-controls";
 65	div4.className = "btn-group";
 66
 67	button1.className = button2.className = button3.className = button4.className = "btn btn-sm btn-outline-secondary";
 68	button1.innerText = "⬅️";
 69	button2.innerText = "*️⃣";
 70	button3.innerText = "🔄";
 71	button4.innerText = "➡️";
 72	button1.addEventListener("click", function() { moveUpDown(element.id, -1); }, false);
 73	button2.addEventListener("click", function() { toggleEntry(element.id); }, false);
 74	button3.addEventListener("click", function() { reloadEntry(element.id); }, false);
 75	button4.addEventListener("click", function() { moveUpDown(element.id, 1); }, false);
 76
 77	div4.appendChild(button1);
 78	div4.appendChild(button2);
 79	div4.appendChild(button3);
 80	div4.appendChild(button4);
 81	div3.appendChild(div4);
 82	div2.appendChild(a);
 83	div2.appendChild(div3);
 84	div1.appendChild(element.canvas);
 85	div1.appendChild(div2);
 86	element.div.appendChild(div1);
 87
 88	const ctx = element.canvas.getContext("2d");
 89
 90	element.image = new Image();
 91	element.image.addEventListener("load", () => {
 92		console.warn("loaded " + element.content);
 93		setBaseImage(element.image, element.canvas, ctx);
 94		addCanvasEvents(element.image, element.canvas, ctx);
 95	});
 96	console.warn("loading " + element.content);
 97	element.image.src = element.content;
 98
 99	return element.div;
100}
101
102async function updateFanartList() {
103	main_container_div.hidden = false;
104	//content_div.innerHTML = ""
105	
106	let i = 0;
107	for (fanart of fanarts) {
108		if(fanart.enabled){
109			i++;
110			fanart.index = i;
111			content_div.appendChild(getNewCardHtml(fanart));
112		}
113	}
114
115	for (fanart of fanarts) {
116		if(!fanart.enabled){
117			fanart.index = 0;
118			content_div.appendChild(getNewCardHtml(fanart));
119		}
120	}
121}
122
123function getFanart(id){
124	return fanarts.find(element => element.id == id)
125}
126
127function toggleEntry(id) {
128	entry = getFanart(id);
129	if (!entry) return;
130
131	entry.enabled = !entry.enabled;
132	updateFanartList()
133}
134
135function reloadEntry(id){
136	const fanart = getFanart(id);
137	if (!fanart) return;
138
139	const old_div = fanart.div;
140	content_div.replaceChild(getNewCardHtml(fanart), old_div);
141	old_div.remove();
142}
143
144function selectAllNone(toggle) {
145	fanarts.map(x => x.enabled = toggle)
146	updateFanartList()
147}
148
149function debugFn(){
150	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":{}}]');
151	controls_div.hidden = false;
152	updateOpacity();
153	updateFanartList();
154}
155
156function toggleColor() {
157	watermark_invert = watermark_invert == '' ? 'invert(1)' : '';
158	updateColorDisplay();
159}
160
161function updateColorDisplay() {
162	togglecolor_button.innerText = watermark_invert ? "⚫" : "⚪";
163}
164
165function addWatermark(event, img, c, ctx) {
166	setBaseImage(img, c, ctx);
167
168	const rect = c.getBoundingClientRect();
169	const x = (event.clientX - rect.left) * c.width / c.clientWidth;
170	const y = (event.clientY - rect.top) * c.height / c.clientHeight;
171
172	ctx.globalAlpha = opacity_range.value;
173	ctx.filter = watermark_invert;
174	ctx.drawImage(WATERMARK, x - (WATERMARK_WIDTH / 2), y - (WATERMARK_HEIGHT / 2), WATERMARK_WIDTH, WATERMARK_HEIGHT);
175}
176
177function updateOpacity() {
178	opacity_label.innerHTML = Math.round(opacity_range.value * 100) + '%';
179}
180
181function setBaseImage(img, c, ctx) {
182	const f = Math.min(MAX_WIDTH / img.width, MAX_HEIGHT / img.height);
183
184	const new_width = c.width = Math.ceil(img.width * f);
185	const new_height = c.height = Math.ceil(img.height * f)
186
187	ctx.imageSmoothingEnabled = (f < 1);
188	ctx.drawImage(img, 0, 0, new_width, new_height);
189}
190
191function moveUpDown(id, amount) {
192	const pos = fanarts.indexOf(fanarts.find(element => element.id == id));
193	const new_pos = pos + amount;
194
195	if (new_pos <= -1 || new_pos >= fanarts.length) {
196		return;
197	}
198
199	[fanarts[pos], fanarts[new_pos]] = [fanarts[new_pos], fanarts[pos]];
200
201	updateFanartList();
202}
203
204async function postData(url = "", data = {}, contentType = "application/x-www-form-urlencoded") {
205    // Default options are marked with *
206    const response = await fetch(url, { method: "POST", headers: { "Content-Type": contentType },
207      //redirect: "follow", // manual, *follow, error
208      //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
209      body: JSON.stringify(data), // body data type must match "Content-Type" header
210    });
211    return response.json();
212}
213
214function getArtworks() {
215    postData("/", { month: month_input.value }, "application/json").then((data) => {
216        console.log(data);
217        fanarts = data;
218        controls_div.hidden = false;
219	    updateOpacity();
220	    updateFanartList();
221    });
222}