Merge pull request #127 from teaxyz/feature/sort-packages

enable visitors to sort packages by popularity and last modified property.
This commit is contained in:
Neil 2022-10-24 19:46:07 +08:00 committed by GitHub
commit 890d857c50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 236 additions and 21 deletions

View file

@ -33,7 +33,7 @@
"maintainer": "pascal",
"thumb_image_url": "/Images/package-thumb-nolabel3.jpg",
"dl_count": 3,
"last_modified": "2022-09-27:39:15.000Z"
"last_modified": "2022-09-27T15:39:15.000Z"
},
{
"name": "h2c",
@ -45,7 +45,7 @@
"maintainer": "h2o",
"thumb_image_url": "/Images/package-thumb-nolabel.jpg",
"dl_count": 4,
"last_modified": "2022-09-25:39:15.000Z"
"last_modified": "2022-09-25T15:39:15.000Z"
},
{
"name": "libmagic",
@ -57,7 +57,7 @@
"maintainer": "",
"thumb_image_url": "/Images/package-thumb-nolabel3.jpg",
"dl_count": 5,
"last_modified": "2022-09-24:39:15.000Z"
"last_modified": "2022-09-24T15:39:15.000Z"
},
{
"name": "deno",
@ -69,7 +69,7 @@
"maintainer": "Ryan Dahl",
"thumb_image_url": "/Images/package-thumb-nolabel2.jpg",
"dl_count": 6,
"last_modified": "2022-09-23:39:15.000Z"
"last_modified": "2022-09-23T15:39:15.000Z"
},
{
"name": "fontconfig",
@ -81,7 +81,7 @@
"maintainer": "Max Miedinger",
"thumb_image_url": "/Images/package-thumb-nolabel.jpg",
"dl_count": 7,
"last_modified": "2022-09-22:39:15.000Z"
"last_modified": "2022-09-22T15:39:15.000Z"
},
{
"name": "pkg-config",
@ -93,7 +93,7 @@
"maintainer": "pascal",
"thumb_image_url": "/Images/package-thumb-nolabel4.jpg",
"dl_count": 8,
"last_modified": "2022-09-21:39:15.000Z"
"last_modified": "2022-09-21T15:39:15.000Z"
},
{
"name": "shared-mime-info",
@ -105,7 +105,7 @@
"maintainer": "Mr.Mime",
"thumb_image_url": "/Images/package-thumb-nolabel3.jpg",
"dl_count": 9,
"last_modified": "2022-09-21:39:15.000Z"
"last_modified": "2022-09-21T15:39:15.000Z"
},
{
"name": "ttfautohint",
@ -117,7 +117,7 @@
"maintainer": "pascal",
"thumb_image_url": "/Images/package-thumb-nolabel.jpg",
"dl_count": 10,
"last_modified": "2022-09-20:39:15.000Z"
"last_modified": "2022-09-20T15:39:15.000Z"
},
{
"name": "numactl",
@ -129,7 +129,7 @@
"maintainer": "FSS",
"thumb_image_url": "/Images/package-thumb-nolabel2.jpg",
"dl_count": 11,
"last_modified": "2022-09-19:39:15.000Z"
"last_modified": "2022-09-19T15:39:15.000Z"
},
{
"name": "flex",
@ -141,6 +141,6 @@
"maintainer": "",
"thumb_image_url": "/Images/package-thumb-nolabel4.jpg",
"dl_count": 12,
"last_modified": "2022-09-18:39:15.000Z"
"last_modified": "2022-09-18T15:39:15.000Z"
}
]

View file

@ -5,7 +5,10 @@
<!-- Package Grid Header -->
<hr>
<div class="container package-grid-header">
<h3>packages</h3>
<section class="flex">
<h3>packages</h3>
{{- partial "sort-dropdown.html" -}}
</section>
<p>There are already plenty of packages available through tea. As the communitea builds the library, contributions will live here.</p>
</div>
<hr>
@ -14,12 +17,11 @@
<!-- Start Package Grid -->
<div class="row package-row black-bg g-0">
<div class="package-grid">
<div id="packageGrid" class="package-grid">
{{ range $.Site.Data.packages }}
{{- partial "package-thumbnail.html" .}}
{{ end }}
</div>
</div>
</div>
<hr>
@ -90,17 +92,60 @@
</style>
<script language="javascript" type="text/javascript">
const sortOptions = {
popularity: 'popularity',
last_modified: 'last_modified',
}
let sortBy = sortOptions.popularity; // last_modified
let sortDirection = 'desc'; // asc
let limit = 16;
const packages = document.querySelectorAll('.card-thumbnail');
const packagesCount = packages.length;
function getPackageThumbs() {
const grid = document.getElementById('packageGrid');
return Array.from(grid.children).filter((e) => e.dataset && e.dataset.name);
}
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() {
for(let i = 0; i < packagesCount; i++) {
const packages = getPackageThumbs();
let i = 0;
for(const sp of packages) {
if (i >= limit) {
packages[i].classList.add('hidden');
sp.classList.add('hidden');
} else {
packages[i].classList.remove('hidden');
sp.classList.remove('hidden');
}
i++;
}
}
@ -112,7 +157,61 @@
const loadMoreSection = document.getElementById('loadMoreSection');
loadMoreSection.classList.add('hidden');
}
},false);
}, false);
refreshDisplayedPackages();
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>

View file

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

View file

@ -0,0 +1,15 @@
<style>
.direction-arrows {
float: right;
}
.direction-arrows span {
opacity: 0.3;
}
.direction-arrows span.active {
opacity: 1;
}
</style>
<div class="direction-arrows">
<span id="{{- . -}}-down-btn">&uarr;</span>
<span id="{{- . -}}-up-btn">&darr;</span>
</div>

View file

@ -0,0 +1,91 @@
<style>
.sorting-container{
display:inline-block;
font-family: "pp-neue-machina", sans-serif;
background-color: #1a1a1a;
border: .5px solid #ffffff;
color: #fff;
padding-top: 0.279vw;
text-decoration: none;
text-transform: uppercase;
max-width: 240px;
width: 100%;
height: 60px;
min-height: 34px;
transition: 0.1s linear;
}
.dropdown {
width: 100%;
height: auto;
position: relative;
display: inline-block;
cursor: pointer;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #1a1a1a;
width: 100%;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
color: white;
list-style: none;
padding: 0px;
}
.dropdown-content li {
position: relative;
padding: 0px 10px;
height: 40px;
width: 100%;
line-height: 40px;
}
.dropdown-content li .sort-btn {
height: 100%;
width: calc(100% - 40px);
opacity: 0.6;
}
.dropdown-content li .sort-btn.active {
font-weight: bold;
opacity: 1;
}
.dropdown-content li .direction-arrows {
position: absolute;
right: 10px;
top: 0px;
}
.dropdown-content li:hover {
background: #00ffd0;
color: black;
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown-title {
height: 60px;
line-height: 60px;
padding-left: 10px;
}
</style>
<section class="sorting-container">
<div class="dropdown">
<div class="dropdown-title">SORT ORDER</div>
<ul class="dropdown-content flex column">
<li><div id="dropdown-popularity-btn" class="sort-btn">POPULARITY</div> {{- partial "sort-direction.html" "popularity"}}</li>
<li><div id="dropdown-last_modified-btn" class="sort-btn">MOST RECENT</div> {{- partial "sort-direction.html" "last_modified"}}</li>
</ul>
</div>
</section>

View file

@ -474,3 +474,13 @@ mark{
display:none;
}
}
.flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.flex.column {
flex-direction: column;
}