Skip to content

Commit 47b1cbf

Browse files
authored
Deploy 1.6.1
Develop 1.6.1 with various fixes/improvements from user feedback.
2 parents 18183d1 + 3531395 commit 47b1cbf

8 files changed

Lines changed: 266 additions & 119 deletions

File tree

index.html

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ <h2>🔁 Weekdays average scores</h2>
198198
<label for="firstDayOfWeekSelect" title="Which day do you want the week to start on">First day of the week</label>
199199
<select id="firstDayOfWeekSelect" class="select">
200200
<option value="1">Monday</option>
201-
<option value="2">Tuesday</option>
201+
<!-- <option value="2">Tuesday</option>
202202
<option value="3">Wednesday</option>
203203
<option value="4">Thursday</option>
204-
<option value="5">Friday</option>
204+
<option value="5">Friday</option> -->
205205
<option value="6">Saturday</option>
206206
<option value="0">Sunday</option>
207207
</select>
@@ -402,6 +402,7 @@ <h3>Image settings</h3>
402402
<option value="0">Hide</option>
403403
<option value="1">Filter word</option>
404404
<option value="2">Compare words</option>
405+
<option value="3">Exclude words</option>
405406
</select>
406407

407408
</div>
@@ -478,8 +479,15 @@ <h3>Image settings</h3>
478479
<div class="chart-container">
479480
<h2>📅 Search Pixels by date</h2>
480481

482+
<div class="options">
483+
<div class="option-item">
484+
<label for="showCalendarCheckbox" title="Show a calendar where you can select a date">Use calendar</label>
485+
<input type="checkbox" id="showCalendarCheckbox" class="checkbox">
486+
</div>
487+
</div>
488+
481489
<div class="option-item">
482-
<label for="dateSearchInput" title="Colors and score type can be selected above">Select date</label>
490+
<label for="dateSearchInput" id="dateSearchInputLabel" title="Colors and score type can be selected above">Select date</label>
483491
<input type="date" id="dateSearchInput" class="input-date">
484492
</div>
485493

@@ -488,10 +496,15 @@ <h2>📅 Search Pixels by date</h2>
488496
</div>
489497

490498
<div class="nav-buttons-card">
491-
<button id="btnPixelPrev" class="nav-button">&lt; Previous</button>
492-
<button id="btnPixelNext" class="nav-button">Next ></button>
499+
<button id="btnPixelPrev" class="nav-button">&lt; Previous day</button>
500+
<button id="btnPixelNext" class="nav-button">Next day ></button>
493501
</div>
494502

503+
<!-- <div class="nav-buttons-card">
504+
<button id="btnPixelPrevYear" class="nav-button">&lt;&lt;&lt; Previous year</button>
505+
<button id="btnPixelNextYear" class="nav-button">Next year >>></button>
506+
</div> -->
507+
495508
<div id="dateSearchResult" class="pixel-date-result"></div>
496509
</div>
497510

@@ -508,8 +521,8 @@ <h2>📅 Search Pixels by date</h2>
508521
<img src="assets/pixels_memories_logo.png" alt="Pixels Memories">
509522
</a>
510523
</div>
511-
<div class="version">Version: v1.5.19</div>
512-
<div class="version">Last update: 2025-09-22</div>
524+
<div class="version">Version: v1.6.1</div>
525+
<div class="version">Last update: 2025-09-26</div>
513526
</footer>
514527

515528
<!-- Charts.js for graphs -->

scripts/card.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
const show_calendar_checkbox = document.querySelector("#showCalendarCheckbox");
12
const input_date = document.querySelector("#dateSearchInput");
3+
const input_date_label = document.querySelector("#dateSearchInputLabel");
24
const calendar_element = document.querySelector("#calendar");
35
const div_date_result = document.querySelector("#dateSearchResult");
46

@@ -116,7 +118,7 @@ async function show_pixel_card(dateStr, scroll = false) {
116118
if (found) {
117119
const card = await create_pixel_card(found);
118120
div_date_result.innerHTML = card.outerHTML;
119-
calendar.gotoDate(dateStr);
121+
if (calendarMode) { calendar.gotoDate(dateStr); }
120122
}
121123
else {
122124
div_date_result.textContent = "No entry found for this date.";
@@ -178,9 +180,23 @@ async function setup_calendar_frame() {
178180
});
179181

180182
calendar.render();
183+
toggle_calendar_view();
181184
}
182185

183186

187+
async function toggle_calendar_view() {
188+
if (calendarMode) {
189+
input_date.style.display = "none";
190+
input_date_label.style.display = "none";
191+
calendar_element.style.display = "block";
192+
}
193+
else {
194+
input_date.style.display = "block";
195+
input_date_label.style.display = "block";
196+
calendar_element.style.display = "none";
197+
}
198+
}
199+
184200
function shift_pixel_date(days) {
185201
const current_date = input_date.value;
186202
if (!current_date) return;
@@ -202,4 +218,9 @@ input_date.addEventListener("change", () => {
202218

203219

204220
btn_pixel_prev.addEventListener("click", () => shift_pixel_date(-1));
205-
btn_pixel_next.addEventListener("click", () => shift_pixel_date(+1));
221+
btn_pixel_next.addEventListener("click", () => shift_pixel_date(+1));
222+
223+
show_calendar_checkbox.addEventListener("change", () => {
224+
calendarMode = show_calendar_checkbox.checked;
225+
toggle_calendar_view();
226+
});

scripts/graphs.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ async function create_tag_frequency_chart() {
272272
animation: !tags_frequency_chart_instance,
273273
maintainAspectRatio: !isMobile,
274274
indexAxis: "y",
275+
plugins: {
276+
legend: {
277+
display: false
278+
},
279+
}
275280
}
276281
});
277282
}
@@ -318,6 +323,11 @@ async function create_tag_score_chart() {
318323
max: 5,
319324
min: 1
320325
}
326+
},
327+
plugins: {
328+
legend: {
329+
display: false
330+
},
321331
}
322332
}
323333
});
@@ -427,6 +437,11 @@ async function create_weekday_chart() {
427437
max: 5,
428438
min: 1
429439
}
440+
},
441+
plugins: {
442+
legend: {
443+
display: false
444+
},
430445
}
431446
}
432447
});
@@ -486,6 +501,11 @@ async function create_month_chart() {
486501
max: 5,
487502
min: 1
488503
}
504+
},
505+
plugins: {
506+
legend: {
507+
display: false
508+
},
489509
}
490510
}
491511
});

scripts/main.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const btn_download_wordcloud = document.querySelector("#btnDownloadWordcloud");
5555

5656
const DEV_MODE = false;
5757
const DEV_FILE_PATH = "../data/pixels.json"
58-
const SCROLL_TO = 100;
58+
const SCROLL_TO = 3500;
5959
const isMobile = window.innerWidth <= 800;
6060
let initial_data = [];
6161
let current_data = [];
@@ -120,28 +120,40 @@ const png_default_settings = {
120120
let png_settings = png_default_settings;
121121

122122
// Card
123+
let calendarMode = false;
123124
let getDynamicBorders = true; // not editable
124125

125126

126127

127128

128-
function show_popup_message(message, type) {
129+
function show_popup_message(message, duration=10000, type="msg") {
129130
const popup = document.createElement("div");
130131
popup.className = "popup-message";
132+
const timerBar = document.createElement("div");
133+
timerBar.className = "popup-timer";
131134
if (type === "error") {
132135
popup.classList.add("error");
136+
timerBar.classList.add("error");
137+
}
138+
else if (type === "success") {
139+
popup.classList.add("success");
140+
timerBar.classList.add("success");
133141
}
134142
popup.textContent = message;
143+
popup.appendChild(timerBar);
144+
popup.style.setProperty("--duration", `${duration}ms`);
135145
document.body.appendChild(popup);
136-
setTimeout(() => popup.classList.add("visible"), 10);
137146

147+
setTimeout(() => popup.classList.add("visible"), 10);
148+
setTimeout(() => timerBar.classList.add("anim"), 50);
138149
setTimeout(() => {
139150
popup.classList.remove("visible");
140-
setTimeout(() => popup.remove(), 3000);
141-
}, 10000);
151+
setTimeout(() => popup.remove(), 2000);
152+
}, duration);
142153
}
143154

144155

156+
145157
function fill_empty_dates(data) {
146158
const datesStrSet = new Set(data.map(entry => pixel_format_date(entry.date)));
147159
const allDates = Array.from(datesStrSet).map(dateStr => new Date(dateStr));
@@ -560,7 +572,7 @@ document.addEventListener("DOMContentLoaded", () => {
560572
const inputs = Array.from(document.querySelectorAll('input, select'));
561573

562574
inputs.forEach(input => {
563-
if (input.type === "file") { return; }
575+
if ((input.type === "file") || (input.type === "color")) { return; }
564576
input.addEventListener('input', store_settings);
565577
});
566578
});

scripts/png.js

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,40 @@ function set_image_settings(settings) {
9595
}
9696

9797

98+
async function update_svg_color(score, color) {
99+
const svg = document.querySelector(`#color${score}`).parentElement.querySelector("svg");
100+
if (svg) {
101+
svg.style.color = color;
102+
}
103+
png_settings.colors[score] = color;
104+
}
105+
106+
107+
async function setup_palette_settings() {
108+
const colors = png_settings.colors;
109+
110+
for (let score = 1; score <= 5; score++) {
111+
const cell = document.querySelector(`#color${score}`).parentElement;
112+
const input = document.getElementById(`color${score}`);
113+
114+
input.classList.add("color-picker-overlay");
115+
116+
let old_svg = cell.querySelector("svg");
117+
if (!old_svg) {
118+
const svg = await load_colored_score_SVG(score);
119+
svg.classList.add("color-icon");
120+
svg.style.color = colors[score];
121+
122+
input.addEventListener("input", () => {
123+
update_svg_color(score, input.value);
124+
});
125+
126+
cell.appendChild(svg);
127+
}
128+
}
129+
}
130+
131+
98132
function get_user_colors(scores_map = null) {
99133
const colors_array = [
100134
setting_color1.value,
@@ -502,6 +536,7 @@ function filter_pixels_by_keyword(keyword, isTag=false) {
502536
current_data.forEach(pixel => {
503537
const date = normalize_date(pixel.date);
504538
const scores = pixel.scores || [];
539+
if (scores.length === 0) { return; }
505540
const notes = normalize_string(pixel.notes || "");
506541

507542
let hasMatch = false;
@@ -527,7 +562,7 @@ function filter_pixels_by_keyword(keyword, isTag=false) {
527562
}
528563

529564

530-
function filter_pixels_by_two_keywords(keyword1, keyword2, isTag1 = false, isTag2 = false) {
565+
function filter_pixels_by_two_keywords(keyword1, keyword2, isTag1 = false, isTag2 = false, exclude = false) {
531566
if (
532567
!keyword1 || keyword1.trim() === "" ||
533568
!keyword2 || keyword2.trim() === "" ||
@@ -544,6 +579,8 @@ function filter_pixels_by_two_keywords(keyword1, keyword2, isTag1 = false, isTag
544579

545580
current_data.forEach(pixel => {
546581
const date = normalize_date(pixel.date);
582+
const scores = pixel.scores || [];
583+
if (scores.length === 0) { return; }
547584

548585
let match1 = false;
549586
let match2 = false;
@@ -578,14 +615,21 @@ function filter_pixels_by_two_keywords(keyword1, keyword2, isTag1 = false, isTag
578615
);
579616
}
580617

581-
if (match1 && match2) {
582-
result.push({ date, scores: [3] });
583-
}
584-
else if (match1) {
585-
result.push({ date, scores: [5] });
586-
}
587-
else if (match2) {
588-
result.push({ date, scores: [1] });
618+
if (exclude) {
619+
if (match1 && !match2) {
620+
result.push({ date, scores });
621+
}
622+
}
623+
else {
624+
if (match1 && match2) {
625+
result.push({ date, scores: [3] });
626+
}
627+
else if (match1) {
628+
result.push({ date, scores: [5] });
629+
}
630+
else if (match2) {
631+
result.push({ date, scores: [1] });
632+
}
589633
}
590634
});
591635

@@ -597,10 +641,11 @@ function get_compare_settings() {
597641
const showFilter = parseInt(setting_showFilter.value, 10);
598642
const compareTag1 = compareSelect1.value === "tag";
599643
const compareTag2 = compareSelect2.value === "tag";
644+
const isExcludeMode = (showFilter === 3);
600645
const value1 = compareTag1 ? compareTagSelect1.value : compareWordInput1.value.trim();
601646
const value2 = compareTag2 ? compareTagSelect2.value : compareWordInput2.value.trim();
602647
if ((showFilter > 1) && value1 && value2) {
603-
return filter_pixels_by_two_keywords(value1, value2, compareTag1, compareTag2);
648+
return filter_pixels_by_two_keywords(value1, value2, compareTag1, compareTag2, isExcludeMode);
604649
}
605650
else if ((showFilter > 0) && value1) {
606651
return filter_pixels_by_keyword(value1, compareTag1);
@@ -620,9 +665,24 @@ async function set_filter_display() {
620665
div_compareSearchOptions1.style.display = (filterState === "0") ? "none" : "flex";
621666
div_compareSearchOptions2.style.display = ((filterState === "0") || (filterState === "1")) ? "none" : "flex";
622667
label_compareSelect1.innerText = (filterState === "2") ? "Compare" : "Filter";
668+
label_compareSelect2.innerText = (filterState === "3") ? "Without" : "With";
623669

624670
label_compareSelect1.style.color = (filterState === "2") ? png_settings.colors[5] : "black";
625671
label_compareSelect2.style.color = (filterState === "2") ? png_settings.colors[1] : "black";
672+
673+
label_compareSelect2.style.textDecoration = (filterState === "3") ?"line-through" : "none";
674+
675+
if (filterState === "1") {
676+
label_compareSelect1.title = "The pixels with this word/tag will be shown";
677+
}
678+
else if (filterState === "2") {
679+
label_compareSelect1.title = "The pixels with this word/tag will be shown in color 5";
680+
label_compareSelect2.title = "The pixels with this word/tag will be shown in color 1";
681+
}
682+
else if (filterState === "3") {
683+
label_compareSelect1.title = "The pixels with this word/tag but without the other will be shown";
684+
label_compareSelect2.title = "The pixels with this word/tag will be hidden from the image";
685+
}
626686
}
627687

628688

@@ -666,6 +726,7 @@ btn_reset_palette_settings.addEventListener("click", () => {
666726

667727
btn_save_palette_settings.addEventListener("click", () => {
668728
close_dialog_settings(save=true);
729+
show_popup_message("Palette settings saved", 3000, "success");
669730
});
670731

671732
btn_save_dialog_settings.addEventListener("click", () => {

0 commit comments

Comments
 (0)