diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1552747..2e157951f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,3 +14,6 @@ Changed for individual apps are listed in `apps/appname/ChangeLog` * Added espruinotools.js for pretokenisation * Included image and compression tools in repo * Added better upload of large files (incl. compression) +* URL fetch is now async +* Adding '#search' after the URL (when not the name of a 'filter' chip) will set up search for that term +* If `bin/pre-publish.sh` has been run and recent.csv created, add 'Sort By' chip diff --git a/bin/pre-publish.sh b/bin/pre-publish.sh new file mode 100755 index 000000000..47822dbf2 --- /dev/null +++ b/bin/pre-publish.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +cd `dirname $0`/.. +node bin/sanitycheck.js || exit 1 + +echo "Sanity check passed." + +echo "Finding most recent apps..." + +cd apps +for appfolder in *; do + echo "$(git log --follow --format=%ai $appfolder),$appfolder" | tail -n 1 ; +done | grep -v _example_ | sort -r > ../recent.csv +cd .. + +echo "Ready to publish" diff --git a/index.html b/index.html index c7c262557..0d23c2c0b 100644 --- a/index.html +++ b/index.html @@ -40,6 +40,9 @@ .chip { cursor: pointer; } + .sort-nav { + float: right; + } .tile-content { position: relative; } .link-github { position:absolute; @@ -88,16 +91,25 @@
-
- - - - - - - - +
+ +
+ + + + + + + + +
+
+
diff --git a/js/index.js b/js/index.js index 7b896b782..94c3e86a4 100644 --- a/js/index.js +++ b/js/index.js @@ -1,5 +1,6 @@ var appJSON = []; // List of apps and info from apps.json var appsInstalled = []; // list of app JSON +var appPublishDates = {}; // list of app publish dates from recent.csv var files = []; // list of files on Bangle var DEFAULTSETTINGS = { pretokenise : true, @@ -19,6 +20,16 @@ httpGet("apps.json").then(apps=>{ refreshFilter(); }); +httpGet("recent.csv").then(csv=>{ + document.querySelector(".sort-nav").classList.remove("hidden"); + csv.split("\n").forEach(line=>{ + var l = line.split(","); + appPublishDates[l[1]] = Date.parse(l[0]); + }); +}).catch(err=>{ + console.log("No recent.csv - app sort disabled"); +}); + // =========================================== Top Navigation function showChangeLog(appid) { var app = appNameToApp(appid); @@ -182,11 +193,12 @@ function showTab(tabname) { // =========================================== Library -var chips = Array.from(document.querySelectorAll('.chip')).map(chip => chip.attributes.filterid.value); +var chips = Array.from(document.querySelectorAll('.filter-nav .chip')).map(chip => chip.attributes.filterid.value); var hash = window.location.hash ? window.location.hash.slice(1) : ''; var activeFilter = !!~chips.indexOf(hash) ? hash : ''; -var currentSearch = ''; +var activeSort = ''; +var currentSearch = activeFilter ? '' : hash; function refreshFilter(){ var filtersContainer = document.querySelector("#librarycontainer .filter-nav"); @@ -194,6 +206,12 @@ function refreshFilter(){ if(activeFilter) filtersContainer.querySelector('.chip[filterid="'+activeFilter+'"]').classList.add('active'); else filtersContainer.querySelector('.chip[filterid]').classList.add('active'); } +function refreshSort(){ + var sortContainer = document.querySelector("#librarycontainer .sort-nav"); + sortContainer.querySelector('.active').classList.remove('active'); + if(activeSort) sortContainer.querySelector('.chip[sortid="'+activeSort+'"]').classList.add('active'); + else sortContainer.querySelector('.chip[sortid]').classList.add('active'); +} function refreshLibrary() { var panelbody = document.querySelector("#librarycontainer .panel-body"); var visibleApps = appJSON; @@ -202,7 +220,7 @@ function refreshLibrary() { if (activeFilter) { if ( activeFilter == "favourites" ) { visibleApps = visibleApps.filter(app => app.id && (favourites.filter( e => e == app.id).length)); - }else{ + } else { visibleApps = visibleApps.filter(app => app.tags && app.tags.split(',').includes(activeFilter)); } } @@ -211,6 +229,13 @@ function refreshLibrary() { visibleApps = visibleApps.filter(app => app.name.toLowerCase().includes(currentSearch) || app.tags.includes(currentSearch)); } + if (activeSort) { + visibleApps = visibleApps.slice(); // clone the array so sort doesn't mess with original + if (activeSort=="new") { + visibleApps = visibleApps.sort((a,b) => appPublishDates[b.id] - appPublishDates[a.id]); + } else throw new Error("Unknown sort type "+activeSort); + } + panelbody.innerHTML = visibleApps.map((app,idx) => { var appInstalled = appsInstalled.find(a=>a.id==app.id); var version = getVersionInfo(app, appInstalled); @@ -580,12 +605,22 @@ filtersContainer.addEventListener('click', ({ target }) => { }); var librarySearchInput = document.querySelector("#searchform input"); - +librarySearchInput.value = currentSearch; librarySearchInput.addEventListener('input', evt => { currentSearch = evt.target.value.toLowerCase(); refreshLibrary(); }); +var sortContainer = document.querySelector("#librarycontainer .sort-nav"); +sortContainer.addEventListener('click', ({ target }) => { + if (target.classList.contains('active')) return; + + activeSort = target.getAttribute('sortid') || ''; + refreshSort(); + refreshLibrary(); + window.location.hash = activeFilter; +}); + // =========================================== About if (window.location.host=="banglejs.com") { diff --git a/js/utils.js b/js/utils.js index 53eeb1868..2b6a6e4c3 100644 --- a/js/utils.js +++ b/js/utils.js @@ -37,7 +37,10 @@ function httpGet(url) { }); oReq.addEventListener("error", () => reject()); oReq.addEventListener("abort", () => reject()); - oReq.open("GET", url); + oReq.open("GET", url, true); + oReq.onerror = function () { + reject("HTTP Request failed"); + }; oReq.send(); }); }