pidgin/nest

c76fb0834ef9
Update the update-lastmod.js file to use date from file

The update-lastmod file was taking the first commit for the specific file and replacing the "date" attribute with the date of the commit. This fix sets the date as the attribute date if it exists and if it doesn't uses the first commit date.

Testing Done:
1. Build docker container
2. Run docker container
3. Run the update-lastmod.js script with node and verified that the files with dates stayed the same and ones without used the first commit.

Reviewed at https://reviews.imfreedom.org/r/640/
/**
* Array representing each plugin row
* @type {{
* elem: HTMLElement,
* head: string,
* info: string,
* repo: string,
* isTrusted: boolean
* }[]}
*/
var pluginRow;
/**
* String Search element
* @type {HTMLInputElement}
*/
var searchTextBox;
var url = new URL(window.location);
var params = url.searchParams;
var searchState = {
/**
* @type {"All" | "Trusted" | "Community"}
*/
publisher: params.get("publisher") || "all",
/**
* String to search for
*/
query: params.get("query") || "",
/**
* What type of plugin has been selected
*/
type: new Set(
(params.get("type") || "")
.split(",")
.map(function(str) {
return str.trim();
})
.filter(Boolean)
),
};
document.addEventListener("DOMContentLoaded", function() {
// Iterate through rows and populate
pluginRow = Array.from($("#plugin-table>tbody>tr")).map(function(elem) {
var contents = function(selectorQuery) {
return $(elem)
.find(selectorQuery)
.text()
.trim();
};
return {
elem,
head: contents(".plugin-heading"),
info: contents(".plugin-info"),
repo: contents(".plugin-repo"),
isTrusted: elem.getAttribute("isTrusted") == "true",
};
});
// Set up publisher selector interface
var publisherSelectors = $("#publisher-selector");
var publisherChecked = $('input[id="' + searchState.publisher + '"]', publisherSelectors);
if (publisherChecked) {
publisherChecked.prop('checked', true);
} else {
searchState.publisher = "all";
$('input[id="all"]', publisherSelectors).prop('checked', true);
}
publisherSelectors.click(updateFilters);
// Set up search box interface
searchTextBox = document.querySelector("#plugin-filter-search");
searchTextBox.value = searchState.query;
searchTextBox.addEventListener(
"input",
// Wait half a second
debounce(500, updateFilters)
);
// Set up plugin type selector interface
Array.from(
document.querySelectorAll("#plugin-selector>label>input")
).forEach(function(elem) {
if (searchState.type.has(elem.dataset.type)) {
elem.checked = true;
}
elem.addEventListener("click", pluginTypeSelectorClickEvent);
});
updateFilters();
$("#plugin-filters,#search-link-wrap").removeClass("hidden");
});
/**
* Event handler for plugin type checkboxes
* @param {MouseEvent} event
* @param {HTMLInputElement} event.target
*/
function pluginTypeSelectorClickEvent({ target }) {
searchState.type[target.checked ? "add" : "delete"](target.dataset.type);
updateFilters();
}
/**
* Visually filters Plugins by toggling visibility
*/
function updateFilters() {
searchState.query = (searchTextBox.value || "").toLowerCase();
searchState.publisher = $('input[name="publisher"]:checked')[0].value;
pluginRow.forEach(function(row) {
if (shouldFilter(row)) {
row.elem.classList.remove("hidden");
} else {
row.elem.classList.add("hidden");
}
});
// Updates query string
params.set("publisher", searchState.publisher);
params.set("query", searchState.query);
params.set("type", Array.from(searchState.type).join(","));
var urlString = String(url);
if (history.pushState) {
history.pushState({ path: urlString }, "", urlString);
}
var link = $("#search-link");
link.attr("href", urlString);
link.text(urlString);
}
/**
* Decides if a plugin row should be filtered
* @param {*} row
* @returns boolean
*/
function shouldFilter(row) {
return (
// Checkboxes
(!searchState.type.size ||
searchState.type.has(row.elem.dataset.type)) &&
// Provider
(searchState.publisher == "all" ||
(searchState.publisher == "pidgin" && row.isTrusted) ||
(searchState.publisher == "community" && !row.isTrusted)) &&
// Search box
(!searchState.query ||
row.head.toLowerCase().includes(searchState.query) ||
row.info.toLowerCase().includes(searchState.query) ||
row.repo.toLowerCase().includes(searchState.query))
);
}
/**
* Simple Debounce function
* @param {time} time
* @param {function} callback
*/
function debounce(time, callback) {
var timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(function() {
callback(...args);
}, time);
};
}