This commit is contained in:
wipedlifepotato
2026-08-29 09:23:31 +03:00
parent 0ee5e04a06
commit 51a6dcd3ec
+176 -110
View File
@@ -1,135 +1,201 @@
<fieldset>
<legend>Torrent Client</legend>
<div id="torrent-ui">
<h3 id="connection_status">_</h3>
<input type="file" id="torrentf" accept=".torrent" style="display:none">
<button onclick="document.getElementById('torrentf').click()">ADd torrent</button>
<ul id="torrents"></ul>
</div>
<legend>Torrent Client</legend>
<div id="torrent-ui">
<h3 id="connection_status">_</h3>
<input type="file" id="torrentf" accept=".torrent" style="display: none" />
<button onclick="document.getElementById('torrentf').click()">
ADd torrent
</button>
<ul id="torrents"></ul>
</div>
</fieldset>
<div id="torrent_details_modal" style="display:none;">
<h3 id="modal_torrent_title"></h3>
<h4>Files:</h4>
<ul id="modal_files_list"></ul>
<h4>Peers (<span id="peer_count">0</span>):</h4>
<ul id="modal_peers_list"></ul>
<h4>Trackers (<span id="trackers_count">0</span>):</h4>
<ul id="modal_trackers_list"></ul>
<button onclick="closeDetailsModal()">Close</button>
<div id="torrent_details_modal" style="display: none">
<h3 id="modal_torrent_title"></h3>
<h4>Files:</h4>
<ul id="modal_files_list"></ul>
<h4>Peers (<span id="peer_count">0</span>):</h4>
<ul id="modal_peers_list"></ul>
<h4>Trackers (<span id="trackers_count">0</span>):</h4>
<ul id="modal_trackers_list"></ul>
<button onclick="closeDetailsModal()">Close</button>
</div>
<script>
let currentTorrentsData = [];
let currentTorrentsData = [];
setInterval(async () => {
const statusIndicator = document.getElementById('connection_status');
if (!window.tjs) return statusIndicator.textContent = 'STATUS: TJS_NOT_LOADED';
setInterval(async () => {
const statusIndicator = document.getElementById("connection_status");
if (!window.tjs)
return (statusIndicator.textContent = "STATUS: TJS_NOT_LOADED");
try {
const r = await window.tjs.getTorrents();
if (!r?.result?.torrents) return statusIndicator.textContent = 'STATUS: INVALID_RESPONSE';
try {
const r = await window.tjs.getTorrents();
if (!r?.result?.torrents)
return (statusIndicator.textContent = "STATUS: INVALID_RESPONSE");
statusIndicator.textContent = 'STATUS: Connected';
statusIndicator.style.color = '#00ff66';
statusIndicator.textContent = "STATUS: Connected";
statusIndicator.style.color = "#00ff66";
const torrents = document.getElementById('torrents');
currentTorrentsData = r.result.torrents;
const torrents = document.getElementById("torrents");
currentTorrentsData = r.result.torrents;
if (currentTorrentsData.length === 0) {
torrents.textContent = '<li>No downloads</li>';
return;
}
if (currentTorrentsData.length === 0) {
torrents.textContent = "<li>No downloads</li>";
return;
}
torrents.innerHTML="";
currentTorrentsData.map(el => {
const percent = el.percentDone ? (el.percentDone*100).toFixed(2) : 0.0;
const speed = window.tjs.formatBytes ? window.tjs.formatBytes(el.rateDownload) : `${el.rateDownload} B/s`;
const speedUp = window.tjs.formatBytes ? window.tjs.formatBytes(el.rateUpload) : `${el.rateUpload} B/s`;
const status = window.tjs.getStatusString ? window.tjs.getStatusString(el.status) : el.status;
const totalSize = el.totalSize; // bytes
const ETA = el.rateDownload ? (((totalSize * (1 - el.percentDone)) / el.rateDownload) / 60).toFixed(1) + " min" : "-";
const name = el.name || '|unknown name, maybe a bad torrent|';
//torrents.textContent =
//return `<li>
// <span></span>
// <button onclick="openTorrentDetails(${el.id})">Details</button>
// <button onclick="removeTorrent(${el.id})">✕</button>
//</li>`;
const li = document.createElement('li');
const span = document.createElement('span')
span.textContent = `${name}${percent}% [${status}] (⬇ ${speed} | ⬆ ${speedUp}) ---- size = ${(totalSize/1024/1024).toFixed(2)}mb; ETA: ${ETA}`
li.appendChild(span)
//
const butDetails = document.createElement('button');
butDetails.textContent = 'Details';
butDetails.onclick = () => openTorrentDetails(el.id);
li.appendChild(butDetails);
//
const butRemove = document.createElement('button');
butRemove.textContent = '✕';
butRemove.onclick = () => removeTorrent(el.id);
li.appendChild(butRemove);
torrents.appendChild(li)
torrents.innerHTML = "";
currentTorrentsData
.map((el) => {
const percent = el.percentDone
? (el.percentDone * 100).toFixed(2)
: 0.0;
const speed = window.tjs.formatBytes
? window.tjs.formatBytes(el.rateDownload)
: `${el.rateDownload} B/s`;
const speedUp = window.tjs.formatBytes
? window.tjs.formatBytes(el.rateUpload)
: `${el.rateUpload} B/s`;
const status = window.tjs.getStatusString
? window.tjs.getStatusString(el.status)
: el.status;
const totalSize = el.totalSize; // bytes
const ETA = el.rateDownload
? (
(totalSize * (1 - el.percentDone)) /
el.rateDownload /
60
).toFixed(1) + " min"
: "-";
const name = el.name || "|unknown name, maybe a bad torrent|";
//torrents.textContent =
//return `<li>
// <span></span>
// <button onclick="openTorrentDetails(${el.id})">Details</button>
// <button onclick="removeTorrent(${el.id})">✕</button>
//</li>`;
const li = document.createElement("li");
const span = document.createElement("span");
span.textContent = `${name}${percent}% [${status}] (⬇ ${speed} | ⬆ ${speedUp}) ---- size = ${(totalSize / 1024 / 1024).toFixed(2)}mb; ETA: ${ETA}`;
li.appendChild(span);
//
const butDetails = document.createElement("button");
butDetails.textContent = "Details";
butDetails.onclick = () => openTorrentDetails(el.id);
li.appendChild(butDetails);
//
const butRemove = document.createElement("button");
butRemove.textContent = "✕";
butRemove.onclick = () => removeTorrent(el.id);
li.appendChild(butRemove);
torrents.appendChild(li);
})
.join("");
} catch (err) {
statusIndicator.textContent =
"STATUS: ERROR_WITH_DATA (f12, check your console and write issue)";
statusIndicator.style.color = "#ff3333";
}
}, 1000);
}).join('');
} catch (err) {
statusIndicator.textContent = 'STATUS: ERROR_WITH_DATA (f12, check your console and write issue)';
statusIndicator.style.color = '#ff3333';
}
}, 1000);
document.getElementById("torrentf").onchange = (e) => {
const file = e.target.files[0];
if (!file) return;
document.getElementById('torrentf').onchange = (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async () => {
const bytes = new Uint8Array(reader.result);
let binary = '';
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
const b64 = btoa(binary);
if (window.tjs) await window.tjs.addTorrent(b64);
e.target.value = '';
};
reader.readAsArrayBuffer(file);
const reader = new FileReader();
reader.onload = async () => {
const bytes = new Uint8Array(reader.result);
let binary = "";
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
const b64 = btoa(binary);
if (window.tjs) await window.tjs.addTorrent(b64);
e.target.value = "";
};
reader.readAsArrayBuffer(file);
};
window.removeTorrent = async (id) => {
if (window.tjs) await window.tjs.removeTorrent(Number(id));
};
window.removeTorrent = async (id) => {
if (window.tjs) await window.tjs.removeTorrent(Number(id));
};
window.openTorrentDetails = (id) => {
const torrent = currentTorrentsData.find(t => String(t.id) === String(id));
if (!torrent) return;
window.openTorrentDetails = (id) => {
const torrent = currentTorrentsData.find(
(t) => String(t.id) === String(id),
);
if (!torrent) return;
document.getElementById('modal_torrent_title').textContent = `DETAILS: ${torrent.name} (#${torrent.id})`;
document.getElementById("modal_torrent_title").textContent =
`DETAILS: ${torrent.name} (#${torrent.id})`;
const filesList = document.getElementById('modal_files_list');
filesList.textContent = torrent.files?.length
? torrent.files.map(f => `<li>${f.name}${(f.bytesCompleted / 1048576).toFixed(2)} / ${(f.length / 1048576).toFixed(2)} MB (${((f.bytesCompleted / f.length) * 100 || 0).toFixed(1)}%)</li>`).join('')
: '<li>NO_FILES</li>';
const filesList = document.getElementById("modal_files_list");
filesList.innerHTML = "";
const peersList = document.getElementById('modal_peers_list');
const trackersList = document.getElementById('modal_trackers_list');
document.getElementById('peer_count').textContent = torrent.peers ? torrent.peers.length : 0;
peersList.textContent = torrent.peers?.length
? torrent.peers.map(p => `<li>${p.address} (${p.clientName || 'Unk'}) — ${(p.rateToClient/1024).toFixed(2)} KB/s — ${(p.rateToPeer/1024).toFixed(2)} KB/s</li>`).join('')
: '<li>NO_PEERS</li>';
if (torrent.files?.length) {
torrent.files.forEach((f) => {
const li = document.createElement("li");
const completedMB = (f.bytesCompleted / 1048576).toFixed(2);
const totalMB = (f.length / 1048576).toFixed(2);
const percent = ((f.bytesCompleted / f.length) * 100 || 0).toFixed(1);
trackersList.textContent = torrent.trackers?.length
? torrent.trackers.map(p => `<li>[id:${p.id}] announce: ${p.announce} ; tier - ${p.tier}</li>`).join('')
: '<li>NO_TRACKERS</li>';
li.textContent = `${f.name}${completedMB} / ${totalMB} MB (${percent}%)`;
filesList.appendChild(li);
});
} else {
const li = document.createElement("li");
li.textContent = "NO_FILES";
filesList.appendChild(li);
}
const peersList = document.getElementById("modal_peers_list");
const trackersList = document.getElementById("modal_trackers_list");
document.getElementById('trackers_count').textContent = torrent.trackers ? torrent.trackers.length : -1;
document.getElementById("peer_count").textContent = torrent.peers
? torrent.peers.length
: 0;
document.getElementById('torrent_details_modal').style.display = 'block';
};
peersList.innerHTML = "";
if (torrent.peers?.length) {
peersList.append(
...torrent.peers.map((p) => {
const li = document.createElement("li");
const downSpeed = (p.rateToClient / 1024).toFixed(2);
const upSpeed = (p.rateToPeer / 1024).toFixed(2);
const client = p.clientName || "Unk";
window.closeDetailsModal = () => {
document.getElementById('torrent_details_modal').style.display = 'none';
};
li.textContent = `${p.address} (${client}) — ${downSpeed} KB/s — ${upSpeed} KB/s`;
return li;
}),
);
} else {
const li = document.createElement("li");
li.textContent = "NO_PEERS";
peersList.appendChild(li);
}
trackersList.innerHTML = "";
if (torrent.trackers?.length) {
trackersList.append(
...torrent.trackers.map((p) => {
const li = document.createElement("li");
li.textContent = `[id:${p.id}] announce: ${p.announce} ; tier - ${p.tier}`;
return li;
}),
);
} else {
const li = document.createElement("li");
li.textContent = "NO_TRACKERS";
trackersList.appendChild(li);
}
document.getElementById("trackers_count").textContent = torrent.trackers
? torrent.trackers.length
: -1;
document.getElementById("torrent_details_modal").style.display = "block";
};
window.closeDetailsModal = () => {
document.getElementById("torrent_details_modal").style.display = "none";
};
</script>