pidgin/nest

41f5bbb6de35
Add a simple convey.yml for building/publishing
<div id="plugin-filters">
<input type="text" id="plugin-filter-search" placeholder="Search plugins" />
<div id="protocol-selector"></div>
</div>
<table id="protocol-table">
<thead>
<th>logo</th>
<th>heading</th>
<th>info</th>
<th>
maintainer<br />
repo
</th>
</thead>
<tbody>
{{ range .Site.Data.plugins }}
<tr data-type="{{.type}}">
<td>
<img src="{{.logo}}" />
</td>
<td class="pulgin-heading">
{{.heading}}
</td>
<td class="pulgin-info">
<b>{{.type}}</b> {{.info | markdownify}}
</td>
<td class="pulgin-repo">
<a href="{{.repo}}">{{.maintainer}}</a>
</td>
</tr>
{{ end }}
</tbody>
</table>
<script>
document.addEventListener("DOMContentLoaded", () => {
const selectorsContainer = document.getElementById("protocol-selector");
const search = document.getElementById("plugin-filter-search");
search.addEventListener("input", debounce(1000 * 0.5, filterRows));
const [, ...rows] = (
document.getElementById("protocol-table")
.getElementsByTagName("tr")
);
const types = {};
const typeFilter = new Set();
const rowinfo = rows.map(elem => {
const type = elem.dataset.type;
if (type) {
if (!types[type]) types[type] = []
types[type].push(elem);
}
return {
elem,
head: getContents("pulgin-heading", elem),
info: getContents("pulgin-info", elem),
repo: getContents("pulgin-repo", elem),
}
})
Object.keys(types).forEach(type => {
const label = createAndAppend("label", selectorsContainer);
label.classList.add('pidgin-plugin-filter-checkbox')
const input = createAndAppend("input", label);
input.type = "checkbox";
input.dataset.type = type
input.addEventListener("click", clickEvent);
label.appendChild(document.createTextNode(type));
});
/////////////////////////
function getContents(className, elem = document){
return (
elem.getElementsByClassName(className)[0]
.textContent.toLowerCase()
)
}
function clickEvent({target}) {
typeFilter[target.checked ? "add" : "delete"](target.dataset.type);
filterRows();
}
function filterRows() {
const str = (search.value || "").toLowerCase()
rowinfo.forEach((row) => {
if (shouldFilter(row, str))
row.elem.classList.remove("filter-hide");
else
row.elem.classList.add("filter-hide");
});
}
function shouldFilter(row, str) {
return (
// Checkboxes
(!typeFilter.size || typeFilter.has(row.elem.dataset.type))
// Search box
&& (
!str
|| row.head.includes(str)
|| row.info.includes(str)
|| row.repo.includes(str)
)
)
}
function debounce(t, fn) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), t);
};
}
function createAndAppend(tag, elem = document) {
return elem.appendChild(document.createElement(tag));
}
});
</script>
<style>
.filter-hide {
display: none;
}
#plugin-filters {
text-align: right;
}
#plugin-filter-search {
text-align: right;
max-width: 250px;
display: inline-block;
}
#protocol-selector label {
text-align: right;
display: inline-block;
}
#protocol-selector input {
margin: 8px;
display: inline-block;
}
</style>