feat: improve upload feedback and peer tracking
Enhanced the file upload feature by replacing the progress bar with a dynamic stats display showing the total amount uploaded and number of peers. Also introduced better differentiation between upload and download sections, improving UI clarity. Added a utility function for generating peer ID hashes. Refactoring ensures users can more easily monitor file sharing progress and understand network interactions.
This commit is contained in:
parent
6b361e3839
commit
93704705c8
2 changed files with 44 additions and 15 deletions
|
@ -9,7 +9,7 @@ async function getRTCIceServers() {
|
|||
async function uploadFile() {
|
||||
const fileInput = document.getElementById("fileInput");
|
||||
const file = fileInput.files[0];
|
||||
const uploadProgressBar = document.getElementById("uploadProgressBar");
|
||||
const uploadStats = document.getElementById("uploadStats");
|
||||
|
||||
if (!file) {
|
||||
alert("Please select a file to upload.");
|
||||
|
@ -25,23 +25,49 @@ async function uploadFile() {
|
|||
rtcConfig: rtcConfig,
|
||||
};
|
||||
|
||||
client.seed(file, opts, (torrent) => {
|
||||
client.seed(file, opts, async (torrent) => {
|
||||
downloadSection.style.display = 'none';
|
||||
uploadSection.style.display = 'block';
|
||||
|
||||
fetch(`/generate-mnemonic/${torrent.infoHash}`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
const uploadResult = document.getElementById("uploadResult");
|
||||
uploadResult.innerHTML = `<p>Sharing your file. Share this mnemonic: <strong>${data.mnemonic}</strong></p>
|
||||
<p>The file will be available for download as long as you keep this page open.</p>`;
|
||||
uploadResult.innerHTML = `File uploaded. Share this mnemonic: <strong>${data.mnemonic}</strong>`;
|
||||
});
|
||||
|
||||
torrent.on("upload", () => {
|
||||
const progress = Math.round((torrent.uploaded / torrent.length) * 100);
|
||||
uploadProgressBar.style.width = `${progress}%`;
|
||||
uploadProgressBar.textContent = `${progress}%`;
|
||||
});
|
||||
let totalPeers = 0;
|
||||
const seenPeers = new Set();
|
||||
|
||||
setInterval(async () => {
|
||||
for (const wire of torrent.wires) {
|
||||
let peerIdHash;
|
||||
try {
|
||||
peerIdHash = await sha256(wire.peerId);
|
||||
} catch (e) {
|
||||
peerIdHash = wire.peerId;
|
||||
}
|
||||
|
||||
if (!seenPeers.has(peerIdHash)) {
|
||||
seenPeers.add(peerIdHash);
|
||||
totalPeers += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const uploaded = (torrent.uploaded / (1024 * 1024)).toFixed(2);
|
||||
uploadStats.innerHTML = `Uploaded: ${uploaded} MB to ${totalPeers} peer(s)`;
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
async function sha256(str) {
|
||||
const buffer = new TextEncoder().encode(str);
|
||||
const hash = await crypto.subtle.digest("SHA-256", buffer);
|
||||
return Array.from(new Uint8Array(hash))
|
||||
.map((b) => b.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
}
|
||||
|
||||
async function downloadFile() {
|
||||
const mnemonicInput = document.getElementById("mnemonicInput").value;
|
||||
const downloadProgressBar = document.getElementById("downloadProgressBar");
|
||||
|
@ -66,6 +92,9 @@ async function downloadFile() {
|
|||
};
|
||||
|
||||
client.add(torrentId, opts, (torrent) => {
|
||||
downloadSection.style.display = 'block';
|
||||
uploadSection.style.display = 'none';
|
||||
|
||||
torrent.files[0].getBlob((err, blob) => {
|
||||
if (err) {
|
||||
const downloadResult = document.getElementById("downloadResult");
|
||||
|
|
|
@ -8,16 +8,14 @@
|
|||
<body>
|
||||
<div class="container">
|
||||
<h1>Transfer.coffee</h1>
|
||||
<div class="section">
|
||||
<div class="section" id="uploadSection">
|
||||
<h2>Share File</h2>
|
||||
<input type="file" id="fileInput" />
|
||||
<button onclick="uploadFile()">Share</button>
|
||||
<div class="progress" id="uploadProgress">
|
||||
<div class="progress-bar" id="uploadProgressBar">0%</div>
|
||||
</div>
|
||||
<div class="result" id="uploadResult"></div>
|
||||
<div class="result" id="uploadStats"></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section" id="downloadSection">
|
||||
<h2>Receive File</h2>
|
||||
<input type="text" id="mnemonicInput" placeholder="Enter mnemonic" />
|
||||
<button onclick="downloadFile()">Receive</button>
|
||||
|
@ -27,7 +25,9 @@
|
|||
<div class="result" id="downloadResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>const trackerUrl = "<%= trackerUrl %>";</script>
|
||||
<script>
|
||||
const trackerUrl = "<%= trackerUrl %>";
|
||||
</script>
|
||||
<script src="/js/index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue