Add manual download from settings

pull/2866/head
v-crispadvice 2023-07-07 19:51:40 +03:00
parent edfb9000e8
commit 597703cda9
7 changed files with 239 additions and 0 deletions

View File

@ -0,0 +1,3 @@
A simple flash cards application based on Trello public board.

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwhC/AH0iABQWKgQXLkAXhCxZIKFxgwKC68zABwWGgYXPmAX/C/4X/C/4X/C9ndACQX/C6dEAAQXS6gXDpovpR/4X/C8ENCyPQC4YA/AGo"))

158
apps/flashcards/app.js Normal file
View File

@ -0,0 +1,158 @@
/**
* Copyright 2023 SHOGEL
* We believe in Finnish
*/
var Layout = require("Layout");
var locale = require("locale");
var storage = require("Storage");
// Constants
let SWAP_SIDE_BUZZ_MILLISECONDS = 50;
let CARD_DATA_FILE = "flashcards.data.json";
let CARD_EMPTY = "empty card";
let CARD_LINE_LENGTH = 9;
let CARD_LINE_FONT = "20%";
// Global variables
let cards = [];
let cardIndex = 0;
let backSide = false;
let lastDragX = 0;
let lastDragY = 0;
// Cards data
function wordWrap(str, maxLength) {
if (maxLength == undefined) {
maxLength = CARD_LINE_LENGTH;
}
let res = '';
while (str.length > maxLength) {
let found = false;
// Inserts new line at first whitespace of the line
for (i = maxLength - 1; i >= 0; i--) {
if (str.charAt(i)==' ') {
res = res + [str.slice(0, i), "\n"].join('');
str = str.slice(i + 1);
found = true;
break;
}
}
// Inserts new line at MAX_LENGTH position, the word is too long to wrap
if (!found) {
res += [str.slice(0, maxLength), "\n"].join('');
str = str.slice(maxLength);
}
}
return res + str;
}
function loadLocalCards() {
if (storage.read(CARD_DATA_FILE))
{
refreshCards(storage.readJSON(CARD_DATA_FILE, 1) || {},false);
}
}
function refreshCards(cardsJSON,showMsg)
{
cardIndex = 0;
backSide = false;
cards = [];
if (cardsJSON && cardsJSON.length) {
cardsJSON.forEach(card => {
cards.push([ wordWrap(card.name), wordWrap(card.desc) ]);
});
}
if (!cards.length) {
cards.push([ wordWrap(CARD_EMPTY), wordWrap(CARD_EMPTY) ]);
drawMessage("e: cards not found");
} else if (showMsg) {
drawMessage("i: cards refreshed");
}
}
// Drawing a card
let drawTimeout;
let queueDraw = function() {
let timeout = 60000;
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, timeout - (Date.now() % timeout));
};
var cardLayout = new Layout( {
type:"v", c: [
{type:"txt", font:"6x8:3", label:"", id:"widgets", fillx:1 },
{type:"txt", font:CARD_LINE_FONT, label:"ABCDEFGHIJ KLMNOPQRST UVWXYZÅÄÖ", filly:1, id:"card" },
{type:"txt", font:"6x8:2", label:"00:00", id:"clock", fillx:1, bgCol:g.theme.fg, col:g.theme.bg }
]
}, {lazy:true});
function drawCard() {
cardLayout.card.label = cards[cardIndex][backSide ? 1 : 0];
cardLayout.clock.label = locale.time(new Date(),1);
cardLayout.render();
}
function drawMessage(msg) {
cardLayout.card.label = wordWrap(msg);
cardLayout.render();
console.log(msg);
}
function draw() {
drawCard();
Bangle.drawWidgets();
queueDraw();
}
// Handle a touch: swap card side
function handleTouch(zone, event) {
backSide = !backSide;
drawCard();
Bangle.buzz(SWAP_SIDE_BUZZ_MILLISECONDS);
}
// Handle a drag event: cycle cards
function handleDrag(event) {
let first_x = event.xy[0];
let last_x = event.xy[event.xy.length - 2];
let xdiff = last_x - first_x;
/*
let first_y = event.xy[1];
let last_y = event.xy[event.xy.length - 1];
let ydiff = last_y - first_y;
*/
if(xdiff > 0) {
cardIndex = (cardIndex + 1) % cards.length;
}
else if(--cardIndex < 0) {
cardIndex = cards.length - 1;
}
drawCard();
}
// initialize
loadLocalCards();
cardLayout.update();
Bangle.loadWidgets();
Bangle.on("touch", handleTouch);
Bangle.on("stroke", handleDrag);
// On start: display the first card
g.clear();
draw();
// cleanup
Bangle.setUI({mode:"clock", remove:function() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
Bangle.removeListener("touch", handleTouch);
Bangle.removeListener("stroke", handleDrag);
}});

BIN
apps/flashcards/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

View File

@ -0,0 +1,21 @@
{
"id": "flashcards",
"name": "Flash Cards",
"shortName": "Flash Cards",
"version": "1.1",
"description": "Flash cards based on public Trello board",
"screenshots" : [ { "url":"screenshot.png" }],
"icon": "app.png",
"tags": "flash cards",
"type": "clock",
"supports": ["BANGLEJS2"],
"storage": [
{"name":"flashcards.app.js","url":"app.js"},
{"name":"flashcards.settings.js","url":"settings.js"},
{"name":"flashcards.img","url":"app-icon.js","evaluate":true}
],
"data": [
{"name":"flashcards.data.json"},
{"name":"flashcards.settings.json"}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,56 @@
(function(back) {
var storage = require("Storage");
var settingsFILE = "flashcards.settings.json";
var dataFile = "flashcards.data.json";
var trelloTimeout = 3000;
var trelloURL = "https://api.trello.com/1/lists/$cardsListId/cards/?fields=name%2Cdesc%2Clist";
var settings = Object.assign({
listId: ""
}, storage.readJSON(settingsFILE, true) || {});
function writeSettings() {
storage.writeJSON(FILE, settings);
}
var settingsMenu = {
"" : { "title" : "Flash Cards" },
"< Back" : () => back(),
"Get from Trello": () => {
E.showPrompt("Download cards?").then((v) => {
let delay = 500;
if (v) {
if (Bangle.http)
{
if (settings.listId.length)
{
delay = delay + trelloTimeout;
E.showMessage('i: downloading');
Bangle.http(trelloURL.replace("$cardsListId", settings.listId),
{
timeout : trelloTimeout,
method: "GET",
headers: { "Content-Type": "application/json" }
}).then(data=>{
var cardsJSON = JSON.parse(data.resp);
storage.write(dataFile, JSON.stringify(result));
E.showMessage('i: downloaded');
})
.catch((e) => {
E.showMessage("e: " + e);
});
} else {
E.showMessage("e: list Id not found");
}
} else {
E.showMessage("e: Gadgetbridge not found");
}
}
setTimeout(() => E.showMenu(settingsMenu), delay);
});
}
}
// Show the menu
E.showMenu(settingsMenu);
})(load)