mirror of https://github.com/espruino/BangleApps
* 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* URL fetch is now asyncpull/415/head
parent
7a46ac82c8
commit
d03fb00f2d
|
@ -14,3 +14,6 @@ Changed for individual apps are listed in `apps/appname/ChangeLog`
|
||||||
* Added espruinotools.js for pretokenisation
|
* Added espruinotools.js for pretokenisation
|
||||||
* Included image and compression tools in repo
|
* Included image and compression tools in repo
|
||||||
* Added better upload of large files (incl. compression)
|
* 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
|
||||||
|
|
|
@ -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"
|
14
index.html
14
index.html
|
@ -40,6 +40,9 @@
|
||||||
.chip {
|
.chip {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.sort-nav {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
.tile-content { position: relative; }
|
.tile-content { position: relative; }
|
||||||
.link-github {
|
.link-github {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
|
@ -88,8 +91,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container bangle-tab" id="librarycontainer">
|
<div class="container bangle-tab" id="librarycontainer">
|
||||||
|
<div>
|
||||||
|
<div class="sort-nav hidden">
|
||||||
|
<span>Sort by:</span>
|
||||||
|
<label class="chip active" sortid="">None</label>
|
||||||
|
<label class="chip" sortid="new">New</label>
|
||||||
|
</div>
|
||||||
<div class="filter-nav">
|
<div class="filter-nav">
|
||||||
<label class="chip active" filterid="">All</label>
|
<label class="chip active" filterid="">Default</label>
|
||||||
<label class="chip" filterid="clock">Clocks</label>
|
<label class="chip" filterid="clock">Clocks</label>
|
||||||
<label class="chip" filterid="game">Games</label>
|
<label class="chip" filterid="game">Games</label>
|
||||||
<label class="chip" filterid="tool">Tools</label>
|
<label class="chip" filterid="tool">Tools</label>
|
||||||
|
@ -98,6 +107,9 @@
|
||||||
<label class="chip" filterid="outdoors">Outdoors</label>
|
<label class="chip" filterid="outdoors">Outdoors</label>
|
||||||
<label class="chip" filterid="favourites">Favourites</label>
|
<label class="chip" filterid="favourites">Favourites</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<div class="input-group" id="searchform">
|
<div class="input-group" id="searchform">
|
||||||
|
|
43
js/index.js
43
js/index.js
|
@ -1,5 +1,6 @@
|
||||||
var appJSON = []; // List of apps and info from apps.json
|
var appJSON = []; // List of apps and info from apps.json
|
||||||
var appsInstalled = []; // list of app 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 files = []; // list of files on Bangle
|
||||||
var DEFAULTSETTINGS = {
|
var DEFAULTSETTINGS = {
|
||||||
pretokenise : true,
|
pretokenise : true,
|
||||||
|
@ -19,6 +20,16 @@ httpGet("apps.json").then(apps=>{
|
||||||
refreshFilter();
|
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
|
// =========================================== Top Navigation
|
||||||
function showChangeLog(appid) {
|
function showChangeLog(appid) {
|
||||||
var app = appNameToApp(appid);
|
var app = appNameToApp(appid);
|
||||||
|
@ -182,11 +193,12 @@ function showTab(tabname) {
|
||||||
|
|
||||||
// =========================================== Library
|
// =========================================== 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 hash = window.location.hash ? window.location.hash.slice(1) : '';
|
||||||
|
|
||||||
var activeFilter = !!~chips.indexOf(hash) ? hash : '';
|
var activeFilter = !!~chips.indexOf(hash) ? hash : '';
|
||||||
var currentSearch = '';
|
var activeSort = '';
|
||||||
|
var currentSearch = activeFilter ? '' : hash;
|
||||||
|
|
||||||
function refreshFilter(){
|
function refreshFilter(){
|
||||||
var filtersContainer = document.querySelector("#librarycontainer .filter-nav");
|
var filtersContainer = document.querySelector("#librarycontainer .filter-nav");
|
||||||
|
@ -194,6 +206,12 @@ function refreshFilter(){
|
||||||
if(activeFilter) filtersContainer.querySelector('.chip[filterid="'+activeFilter+'"]').classList.add('active');
|
if(activeFilter) filtersContainer.querySelector('.chip[filterid="'+activeFilter+'"]').classList.add('active');
|
||||||
else filtersContainer.querySelector('.chip[filterid]').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() {
|
function refreshLibrary() {
|
||||||
var panelbody = document.querySelector("#librarycontainer .panel-body");
|
var panelbody = document.querySelector("#librarycontainer .panel-body");
|
||||||
var visibleApps = appJSON;
|
var visibleApps = appJSON;
|
||||||
|
@ -202,7 +220,7 @@ function refreshLibrary() {
|
||||||
if (activeFilter) {
|
if (activeFilter) {
|
||||||
if ( activeFilter == "favourites" ) {
|
if ( activeFilter == "favourites" ) {
|
||||||
visibleApps = visibleApps.filter(app => app.id && (favourites.filter( e => e == app.id).length));
|
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));
|
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));
|
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) => {
|
panelbody.innerHTML = visibleApps.map((app,idx) => {
|
||||||
var appInstalled = appsInstalled.find(a=>a.id==app.id);
|
var appInstalled = appsInstalled.find(a=>a.id==app.id);
|
||||||
var version = getVersionInfo(app, appInstalled);
|
var version = getVersionInfo(app, appInstalled);
|
||||||
|
@ -580,12 +605,22 @@ filtersContainer.addEventListener('click', ({ target }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
var librarySearchInput = document.querySelector("#searchform input");
|
var librarySearchInput = document.querySelector("#searchform input");
|
||||||
|
librarySearchInput.value = currentSearch;
|
||||||
librarySearchInput.addEventListener('input', evt => {
|
librarySearchInput.addEventListener('input', evt => {
|
||||||
currentSearch = evt.target.value.toLowerCase();
|
currentSearch = evt.target.value.toLowerCase();
|
||||||
refreshLibrary();
|
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
|
// =========================================== About
|
||||||
|
|
||||||
if (window.location.host=="banglejs.com") {
|
if (window.location.host=="banglejs.com") {
|
||||||
|
|
|
@ -37,7 +37,10 @@ function httpGet(url) {
|
||||||
});
|
});
|
||||||
oReq.addEventListener("error", () => reject());
|
oReq.addEventListener("error", () => reject());
|
||||||
oReq.addEventListener("abort", () => reject());
|
oReq.addEventListener("abort", () => reject());
|
||||||
oReq.open("GET", url);
|
oReq.open("GET", url, true);
|
||||||
|
oReq.onerror = function () {
|
||||||
|
reject("HTTP Request failed");
|
||||||
|
};
|
||||||
oReq.send();
|
oReq.send();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue