BangleApps/apps/popconlaunch/boot.ts

117 lines
2.4 KiB
TypeScript
Raw Normal View History

(() => {
2023-05-03 06:50:43 +00:00
type Timestamp = number;
type Cache = {
2023-05-03 06:50:43 +00:00
[key: string]: {
sortorder: number,
pop: number, // amount of launches
last: Timestamp,
}
};
const oldRead = require("Storage").readJSON;
const oneMonth = 1000 * 86400 * 28;
const monthAgo = Date.now() - oneMonth;
let cache: undefined | Cache;
2023-05-03 06:50:43 +00:00
const ensureCache = (): NonNull<typeof cache> => {
if(!cache){
2023-05-03 06:50:43 +00:00
cache = oldRead("popcon.cache.json", true);
if(!cache)
cache = {};
}
2023-05-03 06:50:43 +00:00
return cache;
};
const trimCache = (cache: Cache) => {
const threeMonthsBack = Date.now() - oneMonth * 3;
const del = [];
for(const k in cache)
if(cache[k]!.last < threeMonthsBack)
del.push(k);
for(const k of del)
delete cache[k];
};
const saveCache = (cache: Cache, orderChanged: boolean) => {
trimCache(cache);
require("Storage").writeJSON("popcon.cache.json", cache);
if(orderChanged){
// ensure launchers reload their caches:
const info: AppInfo & { cacheBuster?: boolean } = oldRead("popcon.info", true);
info.cacheBuster = !info.cacheBuster;
require("Storage").writeJSON("popcon.info", info);
2023-05-03 06:50:43 +00:00
}
};
const sortCache = () => {
2023-05-03 06:50:43 +00:00
const ents = Object.values(cache);
ents.sort((a, b) => {
// group the most recently launched apps in the last month,
// then sort by launch count
// then by name
let n;
const am = (a.last > monthAgo) as unknown as number;
const bm = (b.last > monthAgo) as unknown as number;
n = bm - am;
if(n) return n;
n = b.pop - a.pop;
if(n) return n;
// pops are the same, sort by most recent
n = b.last - a.last;
if(n) return n;
if(a.name<b.name) return -1;
if(a.name>b.name) return 1;
return 0;
});
let i = 0;
2023-05-03 21:14:41 +00:00
let orderChanged = false;
2023-05-03 06:50:43 +00:00
for(const ent of ents){
2023-05-03 21:14:41 +00:00
if(ent.sortorder !== i) orderChanged = true;
2023-05-03 06:50:43 +00:00
ent.sortorder = i++;
}
2023-05-03 21:14:41 +00:00
return orderChanged;
};
2023-05-03 06:50:43 +00:00
require("Storage").readJSON = ((fname, skipExceptions) => {
const j: AppInfo = oldRead(fname, skipExceptions);
// ^ technically only AppInfo if we're "*.info"
2023-05-03 06:50:43 +00:00
if(/\.info$/.test(fname)){
const cache = ensureCache();
let so;
2023-05-03 06:50:43 +00:00
if(j.src && (so = cache[j.src]?.sortorder) != null)
2023-05-02 22:08:04 +00:00
j.sortorder = so;
2023-05-03 06:50:43 +00:00
else
2023-05-02 22:08:04 +00:00
j.sortorder = 99;
}
return j;
2023-05-03 06:50:43 +00:00
}) satisfies typeof oldRead;
const oldLoad = load;
2023-05-03 06:50:43 +00:00
global.load = (src: string) => {
if(src){
const cache = ensureCache();
2023-05-02 22:08:04 +00:00
const ent = cache[src] ||= {
2023-05-03 06:50:43 +00:00
pop: 0,
last: 0,
sortorder: -10,
2023-05-02 22:08:04 +00:00
};
2023-05-03 06:50:43 +00:00
ent.pop++;
ent.last = Date.now();
2023-05-03 21:14:41 +00:00
const orderChanged = sortCache();
saveCache(cache, orderChanged);
2023-05-03 06:50:43 +00:00
}
return oldLoad(src);
};
})()