script.js (view raw)
1const DISCOVERY_DOC = "https://sheets.googleapis.com/$discovery/rest?version=v4",
2 DISCOVERY_DOC_DRIVE = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest',
3 SCOPES = "https://www.googleapis.com/auth/spreadsheets.readonly https://www.googleapis.com/auth/drive.metadata.readonly",
4 RANGE = `${SHEET_NAME}!A2:${String.fromCharCode(65 + Math.max(DATE_COL, NAME_COL, URL_COL))}`,
5 WATERMARK = new Image(),
6 date = new Date(),
7 month_input = document.getElementById("month_input"),
8 month_div = document.getElementById("month_div"),
9 authorize_button = document.getElementById("authorize_button"),
10 selectall_button = document.getElementById("selectall_button"),
11 selectnone_button = document.getElementById("selectnone_button"),
12 togglecolor_button = document.getElementById("togglecolor_button"),
13 controls_div = document.getElementById("controls"),
14 opacity_range = document.getElementById("opacity_range"),
15 main_container_div = document.getElementById("main_container"),
16 content_div = document.getElementById("content");
17
18let tokenClient,
19 sheetResult,
20 gapiInited = !1,
21 gisInited = !1,
22 fanarts = new Array(),
23 watermark_invert = '';
24
25WATERMARK.src = WATERMARK_SRC;
26month_input.value = `${date.getFullYear()}-${("0" + (date.getMonth() + 1)).slice(-2)}`;
27
28function gapiLoaded() {
29 gapi.load("client", intializeGapiClient);
30}
31async function intializeGapiClient() {
32 await gapi.client.init({
33 apiKey: API_KEY,
34 discoveryDocs: [DISCOVERY_DOC, DISCOVERY_DOC_DRIVE]
35 })
36 gapiInited = true;
37 maybeEnableButtons();
38}
39
40function gisLoaded() {
41 tokenClient = google.accounts.oauth2.initTokenClient({
42 client_id: CLIENT_ID,
43 scope: SCOPES,
44 callback: ""
45 });
46 gisInited = true;
47 maybeEnableButtons();
48}
49
50function maybeEnableButtons() {
51 gapiInited && gisInited && (authorize_button.hidden = false);
52}
53
54function handleAuthClick() {
55 if(!sheetResult){
56 tokenClient.callback = async (resp) => {
57 if (resp.error !== undefined) {
58 throw (resp);
59 }
60 authorize_button.innerText = "Aggiungi";
61
62 await getSheet();
63 getFanarts();
64 };
65
66 if (gapi.client.getToken() === null) {
67 tokenClient.requestAccessToken({
68 prompt: 'consent'
69 });
70 } else {
71 tokenClient.requestAccessToken({
72 prompt: ''
73 });
74 }
75 } else getFanarts();
76}
77
78async function getLink(id) {
79 let response;
80 try {
81 response = await gapi.client.drive.files.get({
82 'fileId': id,
83 'fields': 'webContentLink'
84 });
85 } catch (err) {
86 console.log(err.message);
87 return;
88 }
89 const files = response.result;
90 if (!files || files.length == 0) {
91 console.log("nessuna risposta");
92 return;
93 }
94 return files['webContentLink'].split("&")[0];
95}
96
97
98async function getSheet() {
99 let e;
100 try {
101 e = await gapi.client.sheets.spreadsheets.values.get({
102 spreadsheetId: SPREADSHEET_ID,
103 range: RANGE
104 })
105 } catch (e) {
106 return void(content_div.innerText = e.message);
107 }
108 const t = e.result;
109 if (!t || !t.values || 0 == t.values.length) return void(content_div.innerText = "No values found.");
110 sheetResult = t.values;
111}
112
113async function getFanarts(){
114 let date, date_str, id;
115 for (x of sheetResult) {
116 date = x[DATE_COL].split(" ")[0].split("/"); // dd/mm/yy hh.mm.ss
117 date_str = `${date[2]}-${date[1]}`;
118
119 if (date_str == month_input.value) { // yyyy-mm
120 id = x[URL_COL].split("=")[1];
121 fanarts.push({
122 'id': id,
123 'date': date,
124 'name': x[NAME_COL],
125 'content': await getLink(id),
126 'enabled': 1
127 })
128 }
129 }
130 if (fanarts) {
131 controls_div.hidden = false;
132 updateOpacity();
133 updateFanartList();
134 //console.log(JSON.stringify(fanarts));
135 }
136}
137
138function addCanvasEvents(img, canvas, ctx){
139 function abc(e) {
140 if (e.button == 0) addWatermark(e, img, canvas, ctx);
141 }
142
143 canvas.addEventListener('mousemove', abc);
144 canvas.addEventListener('mousedown', function(e) {
145 canvas.removeEventListener('mousemove', abc);
146 canvas.addEventListener('mousedown', abc);
147 });
148}
149
150function getNewCardHtml(element) {
151 element.div = document.createElement("div");
152 element.canvas = document.createElement("canvas");
153 const div1 = document.createElement("div"),
154 div2 = document.createElement("div"),
155 a = document.createElement("a"),
156 div3 = document.createElement("div"),
157 div4 = document.createElement("div"),
158 button1 = document.createElement("button"),
159 button2 = document.createElement("button"),
160 button3 = document.createElement("button"),
161 button4 = document.createElement("button");
162
163 element.div.className = `col-md-${BS_COL_WIDTH} entry${element.enabled == 0 ? " entry-disabled" : ""}`;
164 element.div.id = `div-${element.id}`;
165 element.div.setAttribute("data-index", element.index);
166 div1.className = `card mb-${BS_COL_WIDTH} box-shadow my-card`;
167 element.canvas.className = "card-img-top entry-img";
168 element.canvas.id = element.id;
169 element.canvas.setAttribute("data-name", element.name);
170 element.canvas.setAttribute("data-content", element.content);
171 div2.className = "card-body";
172 a.className = "card-text";
173 a.innerText = `${('0' + element.index).slice(-2)} - ${element.name}.png`;
174 a.title = "Clicca per copiare."
175 a.addEventListener("click", function() { navigator.clipboard.writeText(a.innerText); }, false)
176 div3.className = "d-flex justify-content-between align-items-center card-controls";
177 div4.className = "btn-group";
178
179 button1.className = button2.className = button3.className = button4.className = "btn btn-sm btn-outline-secondary";
180 button1.innerText = "⬅️";
181 button2.innerText = "*️⃣";
182 button3.innerText = "🔄";
183 button4.innerText = "➡️";
184 button1.addEventListener("click", function() { moveUpDown(element.id, -1); }, false);
185 button2.addEventListener("click", function() { toggleEntry(element.id); }, false);
186 button3.addEventListener("click", function() { reloadEntry(element.id); }, false);
187 button4.addEventListener("click", function() { moveUpDown(element.id, 1); }, false);
188
189 div4.appendChild(button1);
190 div4.appendChild(button2);
191 div4.appendChild(button3);
192 div4.appendChild(button4);
193 div3.appendChild(div4);
194 div2.appendChild(a);
195 div2.appendChild(div3);
196 div1.appendChild(element.canvas);
197 div1.appendChild(div2);
198 element.div.appendChild(div1);
199
200 const ctx = element.canvas.getContext("2d");
201
202 element.image = new Image();
203 element.image.addEventListener("load", function(){
204 setBaseImage(element.image, element.canvas, ctx);
205 addCanvasEvents(element.image, element.canvas, ctx);
206 }, false);
207 element.image.src = element.content;
208
209 return element.div;
210}
211
212async function updateFanartList() {
213 main_container_div.hidden = false;
214 content_div.innerHTML = ""
215
216 let i = 0;
217 for (fanart of fanarts) {
218 if(fanart.enabled){
219 i++;
220 fanart.index = i;
221 content_div.appendChild(getNewCardHtml(fanart));
222 }
223 }
224
225 for (fanart of fanarts) {
226 if(!fanart.enabled){
227 fanart.index = 0;
228 content_div.appendChild(getNewCardHtml(fanart));
229 }
230 }
231}
232
233function getFanart(id){
234 return fanarts.find(element => element.id == id)
235}
236
237function toggleEntry(id) {
238 entry = getFanart(id);
239 if (!entry) return;
240
241 entry.enabled = !entry.enabled;
242 updateFanartList()
243}
244
245function reloadEntry(id){
246 const fanart = getFanart(id);
247 if (!fanart) return;
248
249 const old_div = fanart.div;
250 content_div.replaceChild(getNewCardHtml(fanart), old_div);
251 old_div.remove();
252}
253
254function selectAllNone(toggle) {
255 fanarts.map(x => x.enabled = toggle)
256 updateFanartList()
257}
258
259function debugFn(){
260 fanarts = JSON.parse('[{"id":"1dE8L7w2DuOfQSJwf5oRjAeJ-VZfy5o-6","date":["03","08","2022"],"name":"Saro","content":"https://drive.google.com/uc?id=1dE8L7w2DuOfQSJwf5oRjAeJ-VZfy5o-6","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":{}}]');
261 controls_div.hidden = false;
262 updateOpacity();
263 updateFanartList();
264}
265
266function toggleColor() {
267 watermark_invert = watermark_invert == '' ? 'invert(1)' : '';
268 updateColorDisplay();
269}
270
271function updateColorDisplay() {
272 togglecolor_button.innerText = watermark_invert ? "⚫" : "⚪";
273}
274
275function addWatermark(event, img, c, ctx) {
276 setBaseImage(img, c, ctx);
277
278 const rect = c.getBoundingClientRect();
279 const x = (event.clientX - rect.left) * c.width / c.clientWidth;
280 const y = (event.clientY - rect.top) * c.height / c.clientHeight;
281
282 ctx.globalAlpha = opacity_range.value;
283 ctx.filter = watermark_invert;
284 ctx.drawImage(WATERMARK, x - (WATERMARK_WIDTH / 2), y - (WATERMARK_HEIGHT / 2), WATERMARK_WIDTH, WATERMARK_HEIGHT);
285}
286
287function updateOpacity() {
288 opacity_label.innerHTML = Math.round(opacity_range.value * 100) + '%';
289}
290
291function setBaseImage(img, c, ctx) {
292 const f = Math.min(MAX_WIDTH / img.width, MAX_HEIGHT / img.height);
293
294 const new_width = c.width = Math.ceil(img.width * f);
295 const new_height = c.height = Math.ceil(img.height * f)
296
297 ctx.imageSmoothingEnabled = (f < 1);
298 ctx.drawImage(img, 0, 0, new_width, new_height);
299}
300
301function moveUpDown(id, amount) {
302 const pos = fanarts.indexOf(fanarts.find(element => element.id == id));
303 const new_pos = pos + amount;
304
305 if (new_pos <= -1 || new_pos >= fanarts.length) {
306 return;
307 }
308
309 [fanarts[pos], fanarts[new_pos]] = [fanarts[new_pos], fanarts[pos]];
310
311 updateFanartList();
312}