#184 fuzzy filter on packages

This commit is contained in:
neil 2022-11-09 20:16:24 +08:00
parent c372e8a74e
commit 17164dfe85
2 changed files with 79 additions and 6 deletions

View file

@ -5,9 +5,12 @@
<!-- Package Grid Header --> <!-- Package Grid Header -->
<hr> <hr>
<div class="container package-grid-header"> <div class="container package-grid-header">
<section class="flex"> <section class="flex flex-column flex-md-row">
<h3>packages</h3> <h3>packages</h3>
<div id="searchBar" class="flex flex-column flex-md-row">
<input id="searchTerm" onsearch="onSearch()" onkeyup="onSearch()" onchange="onSearch()" type="search" placeholder="search_" />
{{- partial "sort-dropdown.html" -}} {{- partial "sort-dropdown.html" -}}
</div>
</section> </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> <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> </div>
@ -89,7 +92,29 @@
border: 0px; border: 0px;
overflow: hidden; overflow: hidden;
} }
#searchBar {
display: flex;
}
#searchBar .sorting-container {
min-width: 260px;
}
#searchBar input {
min-width: 260px;
height: 60px;
padding: 5px 10px;
background-color: #1a1a1a !important;
color: #949494;
outline: none;
border: 2px solid #949494;
border-radius: 0px;
}
#searchBar input::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: white;
opacity: 1; /* Firefox */
}
</style> </style>
<script src="//unpkg.com/string-similarity@4.0.1/umd/string-similarity.min.js"></script>
<script language="javascript" type="text/javascript"> <script language="javascript" type="text/javascript">
const sortOptions = { const sortOptions = {
@ -100,16 +125,56 @@
let sortDirection = 'desc'; // asc let sortDirection = 'desc'; // asc
let limit = 16; let limit = 16;
function getPackageThumbs() {
const grid = document.getElementById('packageGrid'); const grid = document.getElementById('packageGrid');
return Array.from(grid.children).filter((e) => e.dataset && e.dataset.name); 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('searchTerm');
if (searchInput.value) {
const term = searchInput.value;
// refreshDisplayedPackages(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 = '';
for(const sp of sortedPackages) {
const score = getMatchScore(term, sp.dataset);
if (score > 5) {
sp.classList.remove('hidden');
} else {
sp.classList.add('hidden');
}
grid.appendChild(sp);
}
} else {
sortPackages();
}
}, 300);
function getPackageThumbs() {
// const grid = document.getElementById('packageGrid');
return packagesCache;
} }
const packagesCount = getPackageThumbs().length; const packagesCount = getPackageThumbs().length;
function sortPackages() { function sortPackages() {
const packages = getPackageThumbs(); const packages = getPackageThumbs();
const sortedPackages = packages.sort((a, b) => { const sortedPackages = packages.sort((a, b) => {
if (sortBy === sortOptions.popularity) { if (sortBy === sortOptions.popularity) {
const aPop = +a.dataset.popularity; const aPop = +a.dataset.popularity;
@ -149,6 +214,14 @@
} }
} }
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'); const loadMoreButton = document.getElementById('loadMorePackagesBtn');
loadMoreButton.addEventListener('click',() => { loadMoreButton.addEventListener('click',() => {
limit += 16; limit += 16;

View file

@ -1,4 +1,4 @@
<div class="card card-thumbnail" style="width: 100%" data-name="{{- .name -}}" data-popularity="{{- .dl_count -}}" data-last_modified="{{- .last_modified -}}"> <div class="card card-thumbnail" style="width: 100%" data-name="{{- .name -}}" data-popularity="{{- .dl_count -}}" data-last_modified="{{- .last_modified -}}" data-description="{{- .desc -}}">
<figure class="card-img-top" > <figure class="card-img-top" >
<img class="package-image" src="{{- .thumb_image_url -}}" alt="{{- .name -}}" style="width:100%; height:100%;"> <img class="package-image" src="{{- .thumb_image_url -}}" alt="{{- .name -}}" style="width:100%; height:100%;">
<article class="card-thumb-label"> <article class="card-thumb-label">