Skip to content

Commit

Permalink
folderlauncher: add a way to move apps between folders from web inter…
Browse files Browse the repository at this point in the history
…face

Web interface still can not do everything settings on phone can, still
it is very useful to sort applications between folders.
  • Loading branch information
pavelmachek committed Mar 7, 2024
1 parent 7944470 commit 4346973
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 4 deletions.
3 changes: 2 additions & 1 deletion apps/folderlaunch/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
0.01: New app!
0.02: Handle files potentially not existing
0.03: Add setting to disable vibration
0.03: Add setting to disable vibration
0.04: Add glue to allow moving applications from web interface
6 changes: 5 additions & 1 deletion apps/folderlaunch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ Swiping up and down will scroll. Swiping from the left, using the back button, o
* Move app here: Display a list of apps. Selecting one moves it into the folder.
* One menu entry for each subfolder, which opens the folder management menu for that subfolder.
* View apps: Only present if this folder contains apps, Display a menu of all apps in the folder. This is for information only, tapping the apps does nothing.
* Delete folder: Only present if not viewing the root folder. Delete the current folder and move all apps into the parent folder.
* Delete folder: Only present if not viewing the root folder. Delete the current folder and move all apps into the parent folder.

## Web interface

Limited editing is possible from the web interface. You can add folders and move applications between folders.
234 changes: 234 additions & 0 deletions apps/folderlaunch/interface.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../css/spectre.min.css">
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css">
<script type="module">
import vcf from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm'
window.vcf = vcf;
</script>

<style type="text/css">
html, body { height: 100% }
.flex-col { display:flex; flex-direction:column; height:100% }
#map { width:100%; height:100% }
#tab-list { width:100%; height:100% }

/* https://stackoverflow.com/a/58686215 */
.arrow-icon {
width: 14px;
height: 14px;
}
.arrow-icon > div {
margin-left: -1px;
margin-top: -3px;
transform-origin: center center;
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
}

</style>
</head>
<body>
<h1>Folder Launcher v0.04</h1>
<div class="flex-col">
<div id="statusarea">
<button id="download" class="btn btn-error">Reload</button> <button id="upload" class="btn btn-primary">Upload</button>
<span id="status"></span>
<span id="routestatus"></span>
</div>
<div style="flex: 1">
<div id="tab-list">
<table class="table">
<thead>
<tr>
<th>App</th>
<th>Folder</th>
<th>Move to</th>
</tr>
</thead>
<tbody id="list">
</tbody>
</table>
<br>
<h4>Add a new folder</h4>
<form id="add_folder_form">
<div class="columns">
<div class="column col-3 col-xs-8">
<input class="form-input input-sm" type="text" id="add_folder_name" placeholder="Name">
</div>
</div>
<div class="columns">
<div class="column col-3 col-xs-8">
<button id="add_folder_button" class="btn btn-primary btn-sm">Add Folder</button>
</div>
</div>
</form>
</div>
</div>
</div>

<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="../../core/lib/interface.js"></script>

<script>
var json = [];
var folders = [];

// ==========================================================================
/*** status ***/

function clean() {
$('#status').html('<i class="icon icon-check"></i> No pending changes.');
}

function dirty() {
$('#status').html('<b><i class="icon icon-edit"></i> Changes have not been sent to the watch.</b>');
}

/*** util ***/

// https://stackoverflow.com/a/22706073
function escapeHTML(str){
return new Option(str).innerHTML;
}

/*** Bangle.js ***/

function gotStored(pts) {
json = pts;
renderAllApps();
}

// ========================================================================== LIST

var $name = document.getElementById('add_folder_name')
var $form = document.getElementById('add_folder_form')
var $add_folder_button = document.getElementById('add_folder_button')
var $list = document.getElementById('list')

$add_folder_button.addEventListener('click', event => {
event.preventDefault()
var name = $name.value.trim()
if(!name) return;

let n = {};
n.folders = {};
n.apps = [];
json.rootFolder.folders[name] = n;

renderAllApps()
$name.value = ''

dirty();
});

function moveTo(appId, dst){
let config = json;
let path = [];
path.push(dst);
console.log(`Move ${appId} to ${dst}`);

var folder = config.rootFolder;
for (var _i = 0, _a = config.apps[appId].folder; _i < _a.length; _i++) {
var folderName = _a[_i];
folder = folder.folders[folderName];
}
console.log(`Move ${appId} from ${folder}`);
folder.apps = folder.apps.filter(function (item) { return item != appId; });
config.apps[appId].folder = path.slice();
folder = config.rootFolder;
for (var _b = 0, path_2 = path; _b < path_2.length; _b++) {
var folderName = path_2[_b];
folder = folder.folders[folderName];
}
folder.apps.push(appId);
console.log(`Move done?`);
renderAllApps();
dirty();
}

function renderAppsList(){
folders = [];
$list.innerHTML = '';
Object.entries(json.rootFolder.folders).forEach(([name, params]) => {
console.log('Folders:', name);
folders.push(name);
});

Object.entries(json.apps).forEach(([name, params]) => {
let $contact = document.createElement('tr')
let folder = params.folder;
console.log('Foreach', name, folder);
if (folder != '') {
$contact.innerHTML = `<td>${name}</td><td>${folder}</td>`;
} else {
$contact.innerHTML = `<td>${name}</td><td>/</td>`;
}
let buttons = "";
for (let f of folders) {
buttons += `<button class="btn" onclick="moveTo('${name}', '${f}')">${f}</button>`;
}
$contact.innerHTML += `<td>${buttons}</td>`;
$list.appendChild($contact)
});
}

function renderApps() {
renderAppsList();
}

function renderAllApps() {
renderAppsList();
}

// ========================================================================== UPLOAD/DOWNLOAD

function downloadJSONfile(fileid, callback) {
// TODO: use interface.js-provided stuff?
Puck.write(`\x10(function() {
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
Bluetooth.print(JSON.stringify(pts));
})()\n`, contents => {
if (contents=='[{name:"NONE"}]') contents="[]";
var storedpts = JSON.parse(contents);
callback(storedpts);
clean();
});
}

function uploadFile(fileid, contents) {
// TODO: use interface.js-provided stuff?
Puck.write(`\x10(function() {
require("Storage").write("${fileid}",'${contents}');
Bluetooth.print("OK");
})()\n`, ret => {
console.log("uploadFile", ret);
if (ret == "OK")
clean();
});
}

function onInit() {
downloadJSONfile("folderlaunch.json", gotStored);
}

$('#download').on('click', function() {
downloadJSONfile("folderlaunch.json", gotStored);
});

$('#upload').click(function() {
var data = JSON.stringify(json);
uploadFile("folderlaunch.json",data);
});

// ========================================================================== FINALLY...
clean();
renderAllApps();
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion apps/folderlaunch/metadata.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "folderlaunch",
"name": "Folder launcher",
"version": "0.03",
"version": "0.04",
"description": "Launcher that allows you to put your apps into folders",
"icon": "icon.png",
"type": "launch",
Expand All @@ -10,6 +10,7 @@
"BANGLEJS2"
],
"readme": "README.md",
"interface": "interface.html",
"storage": [
{
"name": "folderlaunch.app.js",
Expand Down
2 changes: 1 addition & 1 deletion apps/widadjust/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "widadjust",
"name": "Adjust Clock",
"icon": "icon.png",
"version": "0.03",
"version": "0.04",
"description": "Adjusts clock continually in the background to counter clock drift",
"type": "widget",
"tags": "widget",
Expand Down

0 comments on commit 4346973

Please sign in to comment.