www/src/layouts/partials/package-grid.html
2022-12-21 08:53:12 +08:00

289 lines
8.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- Package Grid -->
<section>
<!-- Package Grid Header -->
<hr>
<div class="container package-grid-header two-boxes">
<section class="flex flex-column flex-md-row">
<h3>packages</h3>
</section>
<p style="width:60%;">There are already plenty of packages available through tea. As the communitea builds the library, contributions will live here. We use <a href="https://stability.ai/blog/stable-diffusion-public-release">Stable Diffusion</a> to generate the artwork for each package using their title and code for input. Thats the power of Open Source.</p>
</div>
<hr>
{{- partial "search-menu.html" "searchTermDesktop" -}}
<hr>
<div class="package-grid">
<!-- Start Package Grid -->
<div class="row package-row black-bg g-0">
<div id="packageGrid" class="package-grid">
{{ range $.Site.Data.packages }}
{{- partial "package-thumbnail.html" .}}
{{ end }}
</div>
{{- partial "no-results-found.html" }}
</div>
</div>
<hr>
<div id="loadMoreSection" class="container small">
<div id="loadMorePackagesBtn"><i class="icon-enter-arrow"></i> SHOW MORE</div>
</div>
</section>
<style>
.container.small {
padding-top: 1em;
padding-bottom: 1em;
}
.package-grid {
display: grid;
grid-template-columns: auto;
}
#loadMorePackagesBtn {
cursor: pointer;
font-size: 2rem;
font-family: "pp-neue-machina", sans-serif;
background-color: #1a1a1a;
color: #fff;
padding-top: 0.279vw;
text-decoration: none;
text-transform: uppercase;
transition: 0.1s linear;
}
#loadMorePackagesBtn .icon-enter-arrow {
display: inline-block;
position: relaitve;
transition: all 0.2s ease-in-out;
}
#loadMorePackagesBtn:hover .icon-enter-arrow{
display: inline-block;
transform: rotate(-45deg) !important;
}
#loadMoreSection.hidden {
display: none;
}
@media only screen and (max-width: 576px) {
#loadMoreSection {
display: none;
}
}
@media only screen and (min-width: 576px) {
.package-grid {
/* changes to 3 column thumbs */
grid-template-columns: auto auto auto;
}
}
@media only screen and (min-width: 992px) {
.package-grid {
/* changes to 4 column thumbs */
grid-template-columns: auto auto auto auto;
}
}
.card-thumbnail.hidden {
height: 0px;
padding: 0px;
margin: 0px;
border: 0px;
overflow: hidden;
}
</style>
<script async src="https://unpkg.com/string-similarity@4.0.1/umd/string-similarity.min.js"></script>
<script language="javascript" type="text/javascript">
const sortOptions = {
popularity: 'popularity',
last_modified: 'last_modified',
}
const showAllPackages = window.location.pathname.includes("/+/");
let sortBy = sortOptions.popularity; // last_modified
let sortDirection = 'desc'; // asc
let limit = 16;
const grid = document.getElementById('packageGrid');
const packagesCache = Array.from(grid.children).filter((e) => e.dataset && e.dataset.name);
function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
const onSearch = debounce(() => {
const searchInput = document.getElementById('searchTermDesktop');
const noResult = document.getElementById('noResult');
if (searchInput.value) {
const term = searchInput.value;
const packages = getPackageThumbs();
const sortedPackages = packages.sort((a, b) => {
const aScore = getMatchScore(term, a.dataset);
const bScore = getMatchScore(term, b.dataset);
return bScore - aScore;
});
const grid = document.getElementById('packageGrid');
grid.textContent = '';
let searchCount = 0;
for(const sp of sortedPackages) {
const score = getMatchScore(term, sp.dataset);
if (score > 20) {
sp.classList.remove('hidden');
searchCount++;
} else {
sp.classList.add('hidden');
}
grid.appendChild(sp);
}
if (searchCount) {
noResult.classList.remove('show');
} else {
noResult.classList.add('show');
}
} else {
noResult.classList.remove('show');
sortPackages();
}
}, 300);
const searchInputDesktop = document.getElementById('searchTermDesktop');
searchInputDesktop.addEventListener("search", onSearch);
searchInputDesktop.addEventListener("change", onSearch);
searchInputDesktop.addEventListener("keyup", onSearch);
function getPackageThumbs() {
// const grid = document.getElementById('packageGrid');
return packagesCache;
}
const packagesCount = getPackageThumbs().length;
function sortPackages() {
const packages = getPackageThumbs();
const sortedPackages = packages.sort((a, b) => {
if (sortBy === sortOptions.popularity) {
const aPop = +a.dataset.popularity;
const bPop = +b.dataset.popularity;
return sortDirection === 'asc' ? aPop-bPop : bPop - aPop;
} else { // last_modified
const aDate = new Date(a.dataset.last_modified);
const bDate = new Date(b.dataset.last_modified);
return sortDirection === 'asc' ? aDate-bDate : bDate - aDate;
}
});
const grid = document.getElementById('packageGrid');
grid.textContent = '';
for(const sp of sortedPackages) {
grid.appendChild(sp);
}
const isPopularity = sortBy === sortOptions.popularity;
setBtnStyles(sortOptions.popularity, isPopularity);
setBtnStyles(sortOptions.last_modified, !isPopularity);
refreshDisplayedPackages();
}
function refreshDisplayedPackages() {
const packages = getPackageThumbs();
let i = 0;
for(const sp of packages) {
if (i >= limit && !showAllPackages) {
sp.classList.add('hidden');
} else {
sp.classList.remove('hidden');
}
i++;
}
}
function getMatchScore(term, dataset) {
// provide higher value with name
const { name, description } = dataset;
const nameScore = stringSimilarity.compareTwoStrings(name, term);
const descriptionScore = stringSimilarity.compareTwoStrings(description, term);
return (nameScore*80) + (descriptionScore*20)
}
const loadMoreButton = document.getElementById('loadMorePackagesBtn');
if (showAllPackages) {
loadMoreSection.classList.add('hidden');
} else {
loadMoreSection.classList.remove('hidden');
}
loadMoreButton.addEventListener('click',() => {
limit += 16;
refreshDisplayedPackages();
if (limit >= packagesCount) {
const loadMoreSection = document.getElementById('loadMoreSection');
loadMoreSection.classList.add('hidden');
}
}, false);
function getSortBtns(type) {
const typeBtn = document.getElementById(`dropdown-${type}-btn`);
const typeDownBtn = document.getElementById(`${type}-down-btn`);
const typeUpBtn = document.getElementById(`${type}-up-btn`);
return { typeBtn, typeDownBtn, typeUpBtn };
}
function setBtnStyles(type, active) {
const { typeBtn, typeDownBtn, typeUpBtn } = getSortBtns(type);
if (active) {
typeBtn.classList.add('active');
if (sortDirection === 'asc') {
typeUpBtn.classList.add('active');
typeDownBtn.classList.remove('active');
} else {
typeDownBtn.classList.add('active');
typeUpBtn.classList.remove('active');
}
} else {
typeBtn.classList.remove('active');
typeDownBtn.classList.remove('active');
typeUpBtn.classList.remove('active');
}
}
function configureSortButton(type) {
const { typeBtn, typeDownBtn, typeUpBtn } = getSortBtns(type);
typeBtn.addEventListener('click',() => {
if (sortBy != type) {
sortBy = type;
sortPackages();
}
}, false);
typeDownBtn.addEventListener('click',() => {
if (sortBy != type || sortDirection != 'desc') {
sortBy = type;
sortDirection = 'desc';
sortPackages();
}
}, false);
typeUpBtn.addEventListener('click',() => {
if (sortBy != type || sortDirection != 'asc') {
sortBy = type;
sortDirection = 'asc';
sortPackages();
}
}, false);
}
configureSortButton(sortOptions.popularity);
configureSortButton(sortOptions.last_modified);
sortPackages();
</script>