pidgin/nest

Update plugin lists

2020-08-19, Elliott Sales de Andrade
a5f1705be525
Update plugin lists

Update plugins that moved off Bitbucket.
Shorten GitHub raw links for plugin logos.
Fix plugin links to anchors.
Use https links where available.
Update some redirecting links.

Testing Done:
Viewed the result, and logos didn't seem to break. Some were even fixed now due to Bitbucket repo deletion.

Reviewed at https://reviews.imfreedom.org/r/72/
/**
* 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);
};
}