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() {
|
async function uploadFile() {
|
||||||
const fileInput = document.getElementById("fileInput");
|
const fileInput = document.getElementById("fileInput");
|
||||||
const file = fileInput.files[0];
|
const file = fileInput.files[0];
|
||||||
const uploadProgressBar = document.getElementById("uploadProgressBar");
|
const uploadStats = document.getElementById("uploadStats");
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
alert("Please select a file to upload.");
|
alert("Please select a file to upload.");
|
||||||
|
@ -25,23 +25,49 @@ async function uploadFile() {
|
||||||
rtcConfig: rtcConfig,
|
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}`)
|
fetch(`/generate-mnemonic/${torrent.infoHash}`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
const uploadResult = document.getElementById("uploadResult");
|
const uploadResult = document.getElementById("uploadResult");
|
||||||
uploadResult.innerHTML = `<p>Sharing your file. Share this mnemonic: <strong>${data.mnemonic}</strong></p>
|
uploadResult.innerHTML = `File uploaded. Share this mnemonic: <strong>${data.mnemonic}</strong>`;
|
||||||
<p>The file will be available for download as long as you keep this page open.</p>`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
torrent.on("upload", () => {
|
let totalPeers = 0;
|
||||||
const progress = Math.round((torrent.uploaded / torrent.length) * 100);
|
const seenPeers = new Set();
|
||||||
uploadProgressBar.style.width = `${progress}%`;
|
|
||||||
uploadProgressBar.textContent = `${progress}%`;
|
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() {
|
async function downloadFile() {
|
||||||
const mnemonicInput = document.getElementById("mnemonicInput").value;
|
const mnemonicInput = document.getElementById("mnemonicInput").value;
|
||||||
const downloadProgressBar = document.getElementById("downloadProgressBar");
|
const downloadProgressBar = document.getElementById("downloadProgressBar");
|
||||||
|
@ -66,6 +92,9 @@ async function downloadFile() {
|
||||||
};
|
};
|
||||||
|
|
||||||
client.add(torrentId, opts, (torrent) => {
|
client.add(torrentId, opts, (torrent) => {
|
||||||
|
downloadSection.style.display = 'block';
|
||||||
|
uploadSection.style.display = 'none';
|
||||||
|
|
||||||
torrent.files[0].getBlob((err, blob) => {
|
torrent.files[0].getBlob((err, blob) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
const downloadResult = document.getElementById("downloadResult");
|
const downloadResult = document.getElementById("downloadResult");
|
||||||
|
|
|
@ -8,16 +8,14 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Transfer.coffee</h1>
|
<h1>Transfer.coffee</h1>
|
||||||
<div class="section">
|
<div class="section" id="uploadSection">
|
||||||
<h2>Share File</h2>
|
<h2>Share File</h2>
|
||||||
<input type="file" id="fileInput" />
|
<input type="file" id="fileInput" />
|
||||||
<button onclick="uploadFile()">Share</button>
|
<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="uploadResult"></div>
|
||||||
|
<div class="result" id="uploadStats"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section">
|
<div class="section" id="downloadSection">
|
||||||
<h2>Receive File</h2>
|
<h2>Receive File</h2>
|
||||||
<input type="text" id="mnemonicInput" placeholder="Enter mnemonic" />
|
<input type="text" id="mnemonicInput" placeholder="Enter mnemonic" />
|
||||||
<button onclick="downloadFile()">Receive</button>
|
<button onclick="downloadFile()">Receive</button>
|
||||||
|
@ -27,7 +25,9 @@
|
||||||
<div class="result" id="downloadResult"></div>
|
<div class="result" id="downloadResult"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>const trackerUrl = "<%= trackerUrl %>";</script>
|
<script>
|
||||||
|
const trackerUrl = "<%= trackerUrl %>";
|
||||||
|
</script>
|
||||||
<script src="/js/index.js"></script>
|
<script src="/js/index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue