Skip to content

Commit 0216789

Browse files
minor cleanup
1 parent b7d3ee1 commit 0216789

File tree

1 file changed

+253
-0
lines changed

1 file changed

+253
-0
lines changed

directory.js

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
// var sort_column = undefined;
2+
// (document.querySelectorAll("th")).forEach((element, indx) => { if (element.textContent == "Path") {sort_column = indx} } );
3+
var sort_column = 2;
4+
5+
let new_directory_name = document.getElementById("name");
6+
let files = document.getElementById("files");
7+
8+
var url_base = window.location;
9+
var current_path;
10+
var editable = undefined;
11+
12+
async function refresh_list() {
13+
14+
function compareValues(a, b) {
15+
if (a.value === b.value) {
16+
return 0;
17+
} else {
18+
return a.value < b.value ? -1 : 1;
19+
}
20+
}
21+
22+
current_path = window.location.hash.substr(1);
23+
if (current_path == "") {
24+
current_path = "/";
25+
}
26+
// Do the fetch first because the browser will prompt for credentials.
27+
const response = await fetch(new URL("/fs" + current_path, url_base),
28+
{
29+
headers: {
30+
"Accept": "application/json"
31+
},
32+
credentials: "include"
33+
}
34+
);
35+
const data = await response.json();
36+
var new_children = [];
37+
var title = document.querySelector("title");
38+
title.textContent = current_path;
39+
var path = document.querySelector("#path");
40+
path.textContent = current_path;
41+
var template = document.querySelector('#row');
42+
43+
if (editable === undefined) {
44+
const status = await fetch(new URL("/fs/", url_base),
45+
{
46+
method: "OPTIONS",
47+
credentials: "include"
48+
}
49+
);
50+
editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE");
51+
new_directory_name.disabled = !editable;
52+
files.disabled = !editable;
53+
if (!editable) {
54+
let usbwarning = document.querySelector("#usbwarning");
55+
usbwarning.style.display = "block";
56+
}
57+
}
58+
59+
var dirCells = [];
60+
var dataCells = [];
61+
var index = 0;
62+
63+
if (window.location.path != "/fs/") {
64+
var clone = template.content.cloneNode(true);
65+
var td = clone.querySelectorAll("td");
66+
td[0].textContent = "🗀";
67+
var path = clone.querySelector("a");
68+
let parent = new URL("..", "file://" + current_path);
69+
path.href = "#" + parent.pathname;
70+
path.textContent = "..";
71+
// Remove the delete button
72+
td[4].replaceChildren();
73+
74+
var sortdata = {};
75+
sortdata.value = "..";
76+
sortdata.index = index;
77+
dirCells.push(sortdata);
78+
index += 1;
79+
80+
new_children.push(clone);
81+
}
82+
83+
for (const f of data) {
84+
// Clone the new row and insert it into the table
85+
var clone = template.content.cloneNode(true);
86+
var td = clone.querySelectorAll("td");
87+
var icon = "⬇";
88+
var file_path = current_path + f.name;
89+
let api_url = new URL("/fs" + file_path, url_base);
90+
let edit_url = "/edit/#" + file_path;
91+
if (f.directory) {
92+
file_path = "#" + file_path + "/";
93+
api_url += "/";
94+
} else {
95+
file_path = api_url;
96+
}
97+
98+
if (f.directory) {
99+
icon = "🗀";
100+
} else if(f.name.endsWith(".txt") ||
101+
f.name.endsWith(".py") ||
102+
f.name.endsWith(".js") ||
103+
f.name.endsWith(".json")) {
104+
icon = "🖹";
105+
} else if (f.name.endsWith(".html")) {
106+
icon = "🌐";
107+
}
108+
td[0].textContent = icon;
109+
td[1].textContent = f.file_size;
110+
var path = clone.querySelector("a");
111+
path.href = file_path;
112+
path.textContent = f.name;
113+
td[3].textContent = (new Date(f.modified_ns / 1000000)).toLocaleString();
114+
var delete_button = clone.querySelector("button.delete");
115+
delete_button.value = api_url;
116+
delete_button.disabled = !editable;
117+
delete_button.onclick = del;
118+
119+
if (editable && !f.directory) {
120+
edit_url = new URL(edit_url, url_base);
121+
let edit_link = clone.querySelector(".edit_link");
122+
edit_link.href = edit_url
123+
}
124+
125+
var dataCell = td[sort_column];
126+
127+
var sortdata = {};
128+
sortdata.value = dataCell.textContent.toLowerCase().trim();
129+
sortdata.index = index;
130+
if (!f.directory) {
131+
dataCells.push(sortdata);
132+
index += 1;
133+
} else {
134+
dirCells.push(sortdata);
135+
index += 1;
136+
}
137+
138+
new_children.push(clone);
139+
}
140+
141+
dirCells.sort(compareValues);
142+
dataCells.sort(compareValues);
143+
144+
var tbody = document.querySelector("tbody");
145+
146+
// remove rows
147+
while (tbody.firstChild) {
148+
tbody.removeChild(tbody.lastChild);
149+
}
150+
151+
// add sorted rows
152+
for (var i = 0; i < dirCells.length; i += 1) {
153+
tbody.appendChild(new_children[dirCells[i].index]);
154+
}
155+
for (var i = 0; i < dataCells.length; i += 1) {
156+
tbody.appendChild(new_children[dataCells[i].index]);
157+
}
158+
}
159+
160+
async function find_devices() {
161+
const version_response = await fetch("/cp/version.json");
162+
if (version_response.ok) {
163+
url_base = new URL("/", window.location).href;
164+
} else {
165+
// TODO: Remove this when we've settled things. It is only used when this file isn't hosted
166+
// by a CP device.
167+
const response = await fetch("http://circuitpython.local/cp/devices.json");
168+
let url = new URL("/", response.url);
169+
url_base = url.href;
170+
const data = await response.json();
171+
}
172+
refresh_list();
173+
}
174+
175+
async function mkdir(e) {
176+
const response = await fetch(
177+
new URL("/fs" + current_path + new_directory_name.value + "/", url_base),
178+
{
179+
method: "PUT",
180+
headers: {
181+
'X-Timestamp': Date.now()
182+
}
183+
}
184+
);
185+
if (response.ok) {
186+
refresh_list();
187+
new_directory_name.value = "";
188+
mkdir_button.disabled = true;
189+
}
190+
}
191+
192+
async function upload(e) {
193+
for (const file of files.files) {
194+
let file_path = new URL("/fs" + current_path + file.name, url_base);
195+
const response = await fetch(file_path,
196+
{
197+
method: "PUT",
198+
headers: {
199+
'Content-Type': 'application/octet-stream',
200+
'X-Timestamp': file.lastModified
201+
},
202+
body: file
203+
}
204+
)
205+
if (response.ok) {
206+
refresh_list();
207+
files.value = "";
208+
upload_button.disabled = true;
209+
}
210+
}
211+
}
212+
213+
async function del(e) {
214+
let fn = new URL(e.target.value);
215+
var prompt = "Delete " + fn.pathname.substr(3);
216+
if (e.target.value.endsWith("/")) {
217+
prompt += " and all of its contents?";
218+
} else {
219+
prompt += "?";
220+
}
221+
if (confirm(prompt)) {
222+
const response = await fetch(e.target.value,
223+
{
224+
method: "DELETE"
225+
}
226+
)
227+
if (response.ok) {
228+
refresh_list();
229+
}
230+
}
231+
}
232+
233+
find_devices();
234+
235+
let mkdir_button = document.getElementById("mkdir");
236+
mkdir_button.onclick = mkdir;
237+
238+
let upload_button = document.getElementById("upload");
239+
upload_button.onclick = upload;
240+
241+
upload_button.disabled = files.files.length == 0;
242+
243+
files.onchange = () => {
244+
upload_button.disabled = files.files.length == 0;
245+
}
246+
247+
mkdir_button.disabled = new_directory_name.value.length == 0;
248+
249+
new_directory_name.oninput = () => {
250+
mkdir_button.disabled = new_directory_name.value.length == 0;
251+
}
252+
253+
window.onhashchange = refresh_list;

0 commit comments

Comments
 (0)