From edbbaa0d54b5a0b899759120bd815ea0065728e5 Mon Sep 17 00:00:00 2001 From: cngcruz Date: Fri, 20 May 2022 19:57:15 -0700 Subject: [PATCH 1/6] adding progress style to conditional rending --- client/src/components/SendFiles.js | 17 +++-- client/src/components/WaitForBumpSender.js | 7 +- client/src/styles/containers.css | 10 +++ client/src/styles/transferinprogress.css | 87 +++++++++++++++++++++- client/src/styles/waitforbump.css | 24 ++---- 5 files changed, 114 insertions(+), 31 deletions(-) diff --git a/client/src/components/SendFiles.js b/client/src/components/SendFiles.js index a0cad1f..c4badac 100644 --- a/client/src/components/SendFiles.js +++ b/client/src/components/SendFiles.js @@ -19,15 +19,20 @@ class SendFiles extends React.Component { // Populates pre component with file names handleFile = (e) => { + // Creating html components + e.preventDefault() const fileListContainer = document.getElementById('fileListContainer') const fileList = document.getElementById('filelist') const userFiles = document.getElementById('files').files - - e.preventDefault() + + // Loop through userFiles and set html data to each file name fileList.innerHTML = '' for (let i = 0; i < userFiles.length; i++) { fileList.innerHTML += userFiles[i].name + '\n\n' } + + // If the list is empty, display nothing + // Else, display the html components if (fileList.innerHTML === '' || fileList.innerHTML === null) { fileList.style.display = 'none' fileListContainer.style.display = 'none' @@ -36,6 +41,7 @@ class SendFiles extends React.Component { fileListContainer.style.display = 'flex' } + // Set the current files state to userFiles this.setState({ files: userFiles }); @@ -45,9 +51,9 @@ class SendFiles extends React.Component { * When the "Send Files" button is clicked, this function is called */ sendButtonClicked = () => { - // FILES TO SEND + // Files to send console.log(this.state.files); - // CREATE TORRENT SEED + // Create torrent seed let returnMagnetLink = this.props.pressedSendButtonCallback; this.state.client.seed(this.state.files, function (torrent) { // console.log("Client is seeding:\n" + torrent.magnetURI); @@ -67,7 +73,6 @@ class SendFiles extends React.Component { {/* Makes it so that when you click "Send", it un-renders the "Choose Files" and "Send" Button */} {this.state.isChoosingFiles && (
- {/* File Choosing */} - - + +
- Fist Bump Waiting Pic


FIST BUMP THE DEVICES diff --git a/client/src/styles/containers.css b/client/src/styles/containers.css index d5f7d3a..7ca07a4 100644 --- a/client/src/styles/containers.css +++ b/client/src/styles/containers.css @@ -12,6 +12,16 @@ ul{ align-items: center; border: 1px solid rgb(107, 107, 107); } +.fileList{ + max-height: 200px; + margin: auto; + padding: auto; +} +.fileListContainer{ + max-height: 200px; + margin: auto; + padding: auto; +} .fileNameContainer{ margin: 0; } diff --git a/client/src/styles/transferinprogress.css b/client/src/styles/transferinprogress.css index 745f4e2..a932e71 100644 --- a/client/src/styles/transferinprogress.css +++ b/client/src/styles/transferinprogress.css @@ -3,17 +3,98 @@ background-color: black; color: white; text-align: center; - width: 500px; + width: 80%; margin: 0 auto; border-radius: 25px; line-height: 1.5; - padding-bottom: 250px; margin-top: 20px; - } .text-style { font-family: 'Bangers', cursive; font-size: 36px; margin-top: 50px; +} + + +/* credit to lukehaas for loading spinner*/ +.loader { + color: #ebebeb; + font-size: 90px; + text-indent: -9999em; + overflow: hidden; + width: 1em; + height: 1em; + border-radius: 50%; + margin: 72px auto; + position: relative; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation: load6 1.7s infinite ease, round 1.7s infinite ease; + animation: load6 1.7s infinite ease, round 1.7s infinite ease; +} +@-webkit-keyframes load6 { + 0% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } + 5%, + 95% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } + 10%, + 59% { + box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; + } + 20% { + box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; + } + 38% { + box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; + } + 100% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } +} +@keyframes load6 { + 0% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } + 5%, + 95% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } + 10%, + 59% { + box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; + } + 20% { + box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; + } + 38% { + box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; + } + 100% { + box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; + } +} +@-webkit-keyframes round { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes round { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } } \ No newline at end of file diff --git a/client/src/styles/waitforbump.css b/client/src/styles/waitforbump.css index 5f95cd6..3c74bf5 100644 --- a/client/src/styles/waitforbump.css +++ b/client/src/styles/waitforbump.css @@ -6,12 +6,6 @@ } .fists-bumping-container { - /* original css - position: absolute; - top: 47%; - left: 50%; - margin-top: -150px; - margin-left: -190px;*/ display: flex; flex-direction: column; align-items: center; @@ -19,13 +13,8 @@ } .fists-bumping-image-size{ - /* original css - margin-top: 30px; - max-width: 380px; - height: auto;*/ max-width: 380px; height: 200px; - margin-bottom: -90px; } .red-button-bottom{ @@ -33,25 +22,22 @@ font-size: 26px; position: relative; bottom: 5%; - /*left: 50%;*/ font-weight: 800; border-radius: 15px; max-width: 350px; min-width:350px; margin: 10px; - /*margin-left: -175px;*/ transition: transform 0.3s ease; background-color: rgba(255,180,176,255); } .test-button { - font-family: "Roboto", sans-serif; font-size: 23px; + border: none; font-weight: 800; - border-radius: 15px; - max-width: 175px; - min-width: 175px; - margin: 10px; + max-width: auto; + min-width: auto; + margin-top: 8%; transition: transform 0.3s ease; - background-color: rgba(153,153,255,255); + background-color: rgba(153,153,255,0); } From dc40b6466c4931fb15c1b0edb50933ae09ff1645 Mon Sep 17 00:00:00 2001 From: cngcruz Date: Fri, 20 May 2022 20:42:34 -0700 Subject: [PATCH 2/6] receive button cond. renders WaitForBumpReceiver --- client/src/components/Home.js | 73 +++++++++++-- client/src/components/ReceiveFiles.js | 108 +++++++++++++++++++ client/src/components/WaitForBumpReceiver.js | 67 ++++++++---- client/src/components/WaitForBumpSender.js | 10 +- 4 files changed, 225 insertions(+), 33 deletions(-) create mode 100644 client/src/components/ReceiveFiles.js diff --git a/client/src/components/Home.js b/client/src/components/Home.js index 7f46bf0..4559c6e 100644 --- a/client/src/components/Home.js +++ b/client/src/components/Home.js @@ -1,10 +1,12 @@ import Header from "./Header" import SuperheroName from "./SuperheroName" import SendFiles from "./SendFiles" -import Receive from './Receive'; +import "../styles/button.css"; +import "../styles/containers.css"; import WaitForBumpSender from './WaitForBumpSender' +import WaitForBumpReceiver from './WaitForBumpReceiver' import React from 'react' -import { APIsend } from './ApiFetch' +import { APIrecv, APIsend } from './ApiFetch' class Home extends React.Component { constructor(props) { @@ -19,6 +21,12 @@ class Home extends React.Component { } } + onReceiveButtonClick = () => { + this.setState({ + appState: "ReadyToReceive", + }); + } + /** * Called by SendFiles when the user has pressed the "Send" button. * @param link: Magnet link send by SendFiles @@ -31,6 +39,18 @@ class Home extends React.Component { console.log("Magnet Link: ", link); } + /** + * Called by ReceiveFiles when the user has pressed the "Receive" button. + * @param link: ReceiveFiles receives magnet link from db + */ + pressedReceiveButtonCallback = (link) => { + this.setState({ + appState: "ReadyToReceive", + magnetLink: link, + }); + console.log("Magnet Link: ", link); + } + /** * Called by WaitForBumpSender when a BAM/Bump has been detected * @param sensorData: Coordinates and Date sent by WaitForBumpSender @@ -48,23 +68,56 @@ class Home extends React.Component { APIsend(clientData); } + + /** + * Called by WaitForBumpReceiver when a BAM/Bump has been detected + * @param sensorData: Coordinates and Date received by WaitForBumpReceiver from db + */ + receiveBumpCallback = (sensorData) => { + console.log("Sender BAM!", sensorData); + + // Build the API request body + const clientData = { + name: "Placeholder", + magnetLink: this.state.magnetLink, + coordinates: sensorData.coordinates, + date: sensorData.date, + } + + APIrecv(clientData); + } render() { return (
- {this.state.appState == "Choosing" &&
} + {(this.state.appState == "Choosing" || this.state.appState == "ReadyToReceive") &&
} {this.state.appState == "Choosing" && } - - + {this.state.appState != "ReadyToReceive" && ( + + )} + {this.state.appState == "ReadyToSend" && ( )} - - {this.state.appState == "Choosing" && } + + {this.state.appState != "ReadyToReceive" && ( + + )} + + {this.state.appState == "ReadyToReceive" && ( + + )} +
); } diff --git a/client/src/components/ReceiveFiles.js b/client/src/components/ReceiveFiles.js new file mode 100644 index 0000000..ffe0236 --- /dev/null +++ b/client/src/components/ReceiveFiles.js @@ -0,0 +1,108 @@ +import '../styles/button.css' +import '../styles/index.css' +import 'bootstrap/dist/css/bootstrap.min.css' +import React from 'react' +import PropTypes from 'prop-types'; + +/** + * SendFiles handles all the sending files logic. + */ +class ReceiveFiles extends React.Component { + constructor(props) { + super(props); + this.state = { + files: null, + isChoosingFiles: true, + client: this.props.client, + } + } + + // Populates pre component with file names + handleFile = (e) => { + // Creating html components + e.preventDefault() + const fileListContainer = document.getElementById('fileListContainer') + const fileList = document.getElementById('filelist') + const userFiles = document.getElementById('files').files + + // Loop through userFiles and set html data to each file name + fileList.innerHTML = '' + for (let i = 0; i < userFiles.length; i++) { + fileList.innerHTML += userFiles[i].name + '\n\n' + } + + // If the list is empty, display nothing + // Else, display the html components + if (fileList.innerHTML === '' || fileList.innerHTML === null) { + fileList.style.display = 'none' + fileListContainer.style.display = 'none' + } else { + fileList.style.display = 'block' + fileListContainer.style.display = 'flex' + } + + // Set the current files state to userFiles + this.setState({ + files: userFiles + }); + } + + /** + * When the "Send Files" button is clicked, this function is called + */ + sendButtonClicked = () => { + // Files to send + console.log(this.state.files); + // Create torrent seed + let returnMagnetLink = this.props.pressedSendButtonCallback; + this.state.client.seed(this.state.files, function (torrent) { + // console.log("Client is seeding:\n" + torrent.magnetURI); + returnMagnetLink(torrent.magnetURI); + }); + + this.setState({ isChoosingFiles: false }); + } + + render() { + return ( +
+
+

+        
+ + {/* Makes it so that when you click "Send", it un-renders the "Choose Files" and "Send" Button */} + {this.state.isChoosingFiles && ( +
+ {/* File Choosing */} + + + {/* Send Files button */} + {/* Don't render "Send" Button if no files were chosen */} + {this.state.files && this.state.files.length > 0 && ( +
+ +
+ )} + +
+ )} +
+ ); + } +} + +// Declaring prop types +ReceiveFiles.propTypes = { + client: PropTypes.object, + pressedSendButtonCallback: PropTypes.func, +}; + +export default ReceiveFiles; diff --git a/client/src/components/WaitForBumpReceiver.js b/client/src/components/WaitForBumpReceiver.js index b31387e..7f2be40 100644 --- a/client/src/components/WaitForBumpReceiver.js +++ b/client/src/components/WaitForBumpReceiver.js @@ -1,35 +1,64 @@ import React from 'react' -import Header from './Header' -import SuperheroName from './SuperheroName' import '../styles/button.css' import '../styles/waitforbump.css' import 'bootstrap/dist/css/bootstrap.min.css' import { useNavigate } from 'react-router-dom' import FistsBumping from '../assets/FistsBumping.png' +import PropTypes from 'prop-types'; -const WaitForBumpReceiver = () => { - const navigate = useNavigate() - return ( -
-
- - -
- Fist Bump Waiting Pic +class WaitForBumpReceiver extends React.Component { + constructor(props) { + super(props); + } + + cancelReceive = () => { + useNavigate('/'); + } + + render(){ return ( +
+ + +


FIST BUMP THE DEVICES
TO INITIATE TRANSFER!

-
- -
- ) +
+ + +
+ )} } +// const navigate = useNavigate() +// return ( +//
+// +//
+// Fist Bump Waiting Pic +//

+//
+// FIST BUMP THE DEVICES +//
+// TO INITIATE TRANSFER! +//

+//
+// +//
+// ) +// } + +// Declaring prop types +WaitForBumpReceiver.propTypes = { + bumpCallback: PropTypes.func, +}; export default WaitForBumpReceiver \ No newline at end of file diff --git a/client/src/components/WaitForBumpSender.js b/client/src/components/WaitForBumpSender.js index 84ed785..defc48d 100644 --- a/client/src/components/WaitForBumpSender.js +++ b/client/src/components/WaitForBumpSender.js @@ -18,6 +18,10 @@ class WaitForBumpSender extends React.Component { } this.props.bumpCallback(sensorData); } + + cancelSend = () => { + useNavigate('/'); + } render(){ return (
@@ -34,10 +38,8 @@ class WaitForBumpSender extends React.Component {

- -
+ + )} } From dbde1eafaddf427513a24f8c5a9b48c5965e595e Mon Sep 17 00:00:00 2001 From: cngcruz Date: Fri, 20 May 2022 21:09:31 -0700 Subject: [PATCH 3/6] simulate receive button receives files --- client/src/components/SendFiles.js | 1 + client/src/components/WaitForBumpReceiver.js | 126 +++++++++++++++---- 2 files changed, 103 insertions(+), 24 deletions(-) diff --git a/client/src/components/SendFiles.js b/client/src/components/SendFiles.js index c4badac..49f88a0 100644 --- a/client/src/components/SendFiles.js +++ b/client/src/components/SendFiles.js @@ -54,6 +54,7 @@ class SendFiles extends React.Component { // Files to send console.log(this.state.files); // Create torrent seed + console.log(this.state.client) let returnMagnetLink = this.props.pressedSendButtonCallback; this.state.client.seed(this.state.files, function (torrent) { // console.log("Client is seeding:\n" + torrent.magnetURI); diff --git a/client/src/components/WaitForBumpReceiver.js b/client/src/components/WaitForBumpReceiver.js index 7f2be40..c0dc993 100644 --- a/client/src/components/WaitForBumpReceiver.js +++ b/client/src/components/WaitForBumpReceiver.js @@ -1,14 +1,109 @@ import React from 'react' import '../styles/button.css' +import "../styles/containers.css"; import '../styles/waitforbump.css' import 'bootstrap/dist/css/bootstrap.min.css' +import { APIrecv } from "./ApiFetch"; import { useNavigate } from 'react-router-dom' import FistsBumping from '../assets/FistsBumping.png' +import JSZip from "../../node_modules/jszip/dist/jszip"; +import downloadIcon from "../assets/download.png"; import PropTypes from 'prop-types'; - +/* +\ +*/ class WaitForBumpReceiver extends React.Component { constructor(props) { super(props); + this.state = { + client: this.props.client, + } + } + + bamEvent = () => { + var zip = new JSZip(); + let addedFiles = 0; + const clientData = { + name: "Superman", + // magnetLink: "", + coordinates: [115, 115], + date: Date.now(), + }; + if(this.state.client == null){ + const { WebTorrent } = window + this.setState({ + client: new WebTorrent() + }); + } + APIrecv(clientData).then((response) => { + console.log("Torrent ID: ", response.magnetLink); + + let torrentId = response.magnetLink; + // https://webtorrent.io/docs + console.log(this.state.client) + this.state.client.add(torrentId, function (torrent) { + torrent.files.forEach(function (file) { + zip.file(file.path, Blob, { base64: true }); + // temporary code. will be replaced with updating Parent Component torr state + file.getBlob(function (err, blob) { + addedFiles += 1; + if (err) throw err; + + // add file to zip + zip.file(file.path, blob); + + // start the download when all files have been added + if (addedFiles === torrent.files.length) { + if (torrent.files.length > 1) { + // generate the zip relative to the torrent folder + zip = zip.folder(torrent.name); + } + zip.generateAsync({ type: "blob" }).then(function (blob) { + let downloadList = document.getElementById("downloadList"); + let fileRow = document.createElement("div"); + fileRow.className = "downloadAllContainer"; + downloadList.appendChild(fileRow); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.download = "downloaded_files"; + a.href = url; + a.textContent = "Download All Files"; + a.className = "downloadAllButton"; + fileRow.appendChild(a); + setTimeout(function () { + URL.revokeObjectURL(url); + }, 30 * 1000); + }); + } + }); + file.getBlobURL(function callback(err, url) { + if (err) throw err; + // Create the list + let downloadList = document.getElementById("downloadList"); + let fileRow = document.createElement("div"); + fileRow.className = "row fileRow"; + downloadList.appendChild(fileRow); + + var p = document.createElement("p"); + p.innerHTML = file.name; + p.className = "col-10 fileNameContainer"; + + var a = document.createElement("a"); + a.download = file.name; + a.href = url; + a.className = "col-4 downloadButton"; + + var img = document.createElement("img"); + img.className = "downloadIcon"; + img.src = downloadIcon; + a.appendChild(img); + + fileRow.appendChild(p); + fileRow.appendChild(a); + }); + }); + }); + }); } cancelReceive = () => { @@ -29,36 +124,19 @@ class WaitForBumpReceiver extends React.Component { TO INITIATE TRANSFER! - +
)} } -// const navigate = useNavigate() -// return ( -//
-// -//
-// Fist Bump Waiting Pic -//

-//
-// FIST BUMP THE DEVICES -//
-// TO INITIATE TRANSFER! -//

-//
-// -//
-// ) -// } // Declaring prop types WaitForBumpReceiver.propTypes = { - bumpCallback: PropTypes.func, + client: PropTypes.object, + bumpCallback: PropTypes.func }; export default WaitForBumpReceiver \ No newline at end of file From 4fc4cb431a6dcb55622c8c2377752c1f1c1e51b6 Mon Sep 17 00:00:00 2001 From: cngcruz Date: Fri, 20 May 2022 23:08:44 -0700 Subject: [PATCH 4/6] receive functionality working with conditional rendering. general styling. cleaned and commented code. --- client/src/components/Home.js | 20 ++-- client/src/components/Receive.js | 5 + client/src/components/WaitForBumpReceiver.js | 96 ++++++++++++++++---- client/src/components/WaitForBumpSender.js | 16 ++-- client/src/styles/containers.css | 1 + client/src/styles/transferinprogress.css | 4 +- client/src/styles/waitforbump.css | 1 + 7 files changed, 103 insertions(+), 40 deletions(-) diff --git a/client/src/components/Home.js b/client/src/components/Home.js index 4559c6e..5f83e18 100644 --- a/client/src/components/Home.js +++ b/client/src/components/Home.js @@ -23,7 +23,7 @@ class Home extends React.Component { onReceiveButtonClick = () => { this.setState({ - appState: "ReadyToReceive", + appState: "WaitingToReceive", }); } @@ -90,21 +90,20 @@ class Home extends React.Component { render() { return (
- {(this.state.appState == "Choosing" || this.state.appState == "ReadyToReceive") &&
} + {(this.state.appState == "Choosing" || this.state.appState == "WaitingToReceive") &&
} {this.state.appState == "Choosing" && } - {this.state.appState != "ReadyToReceive" && ( - - )} + />} {this.state.appState == "ReadyToSend" && ( )} - {this.state.appState != "ReadyToReceive" && ( + {this.state.appState == "Choosing" && (
diff --git a/client/src/components/Receive.js b/client/src/components/Receive.js index 41de59d..0b09440 100644 --- a/client/src/components/Receive.js +++ b/client/src/components/Receive.js @@ -40,6 +40,11 @@ const Receive = ({ torrent }) => { let torrentId = response.magnetLink; // https://webtorrent.io/docs client.add(torrentId, function (torrent) { + while (torrent.progress != 1) { + console.log('Progress: ' + (torrent.progress * 100).toFixed(1) + '%') + setProgress((torrent.progress * 100).toFixed(1)); + setInterval() + } torrent.files.forEach(function (file) { zip.file(file.path, Blob, { base64: true }); // temporary code. will be replaced with updating Parent Component torr state diff --git a/client/src/components/WaitForBumpReceiver.js b/client/src/components/WaitForBumpReceiver.js index c0dc993..ef54a56 100644 --- a/client/src/components/WaitForBumpReceiver.js +++ b/client/src/components/WaitForBumpReceiver.js @@ -1,7 +1,8 @@ import React from 'react' import '../styles/button.css' -import "../styles/containers.css"; +import "../styles/containers.css" import '../styles/waitforbump.css' +import '../styles/transferinprogress.css' import 'bootstrap/dist/css/bootstrap.min.css' import { APIrecv } from "./ApiFetch"; import { useNavigate } from 'react-router-dom' @@ -9,101 +10,145 @@ import FistsBumping from '../assets/FistsBumping.png' import JSZip from "../../node_modules/jszip/dist/jszip"; import downloadIcon from "../assets/download.png"; import PropTypes from 'prop-types'; + /* -\ + Waiting for Bump Receiver page + + Receiver renders this component after clicking Receive button on Home + Currently, this component simulates the BAM action and starts receiving files + Later, application should render TransferInProgress while downloading + Then, render ReceiveFiles once done downloading + But for now, this component contains all that functionality + */ class WaitForBumpReceiver extends React.Component { constructor(props) { super(props); this.state = { client: this.props.client, + showProgress: false } } + // (will be) Called when detected BAM action bamEvent = () => { - var zip = new JSZip(); let addedFiles = 0; + var zip = new JSZip(); const clientData = { name: "Superman", // magnetLink: "", coordinates: [115, 115], date: Date.now(), }; + + // Check if the client has been created and created one if false if(this.state.client == null){ const { WebTorrent } = window this.setState({ client: new WebTorrent() }); } + + // Display loading spinner (and progress) + this.setState({ + showProgress: true + }) + + // API fetch call to grab magnet link from matching sender APIrecv(clientData).then((response) => { + + // Log response console.log("Torrent ID: ", response.magnetLink); - let torrentId = response.magnetLink; + // https://webtorrent.io/docs - console.log(this.state.client) + // Start downloading torrent this.state.client.add(torrentId, function (torrent) { + + // Loop through each file in the torrent torrent.files.forEach(function (file) { + + // Set the parameters for the zip file zip.file(file.path, Blob, { base64: true }); - // temporary code. will be replaced with updating Parent Component torr state + + // Start zip into blob object for href download file.getBlob(function (err, blob) { - addedFiles += 1; if (err) throw err; - - // add file to zip + addedFiles += 1; + + // Add file path to zip zip.file(file.path, blob); - // start the download when all files have been added + // Start the download when all files have been added if (addedFiles === torrent.files.length) { - if (torrent.files.length > 1) { - // generate the zip relative to the torrent folder - zip = zip.folder(torrent.name); - } + + // Name the the file in the zip and start generating each file component + if (torrent.files.length > 1) { zip = zip.folder(torrent.name);} zip.generateAsync({ type: "blob" }).then(function (blob) { + // Start creating and editing html components let downloadList = document.getElementById("downloadList"); let fileRow = document.createElement("div"); fileRow.className = "downloadAllContainer"; - downloadList.appendChild(fileRow); const url = URL.createObjectURL(blob); + + // Create Download All Files button html component const a = document.createElement("a"); a.download = "downloaded_files"; a.href = url; a.textContent = "Download All Files"; a.className = "downloadAllButton"; + + // Add components to html body fileRow.appendChild(a); + downloadList.appendChild(fileRow); setTimeout(function () { URL.revokeObjectURL(url); }, 30 * 1000); }); } }); + + // Start turning each individual file into blob object file.getBlobURL(function callback(err, url) { if (err) throw err; - // Create the list + + // Start creating and editing html components let downloadList = document.getElementById("downloadList"); let fileRow = document.createElement("div"); fileRow.className = "row fileRow"; downloadList.appendChild(fileRow); - + + // Create html component for file names var p = document.createElement("p"); p.innerHTML = file.name; p.className = "col-10 fileNameContainer"; + // Create html component for individual download button var a = document.createElement("a"); a.download = file.name; a.href = url; a.className = "col-4 downloadButton"; + // Insert download image into button var img = document.createElement("img"); img.className = "downloadIcon"; img.src = downloadIcon; a.appendChild(img); + // Add components to html body fileRow.appendChild(p); fileRow.appendChild(a); }); }); }); - }); + + // Once torrent is done downloading, stop showing loading spinner/progress + }).then(() => { + setTimeout(function () {}, 30 * 1000); + this.setState({ + showProgress: false + }) + }) } cancelReceive = () => { @@ -112,6 +157,7 @@ class WaitForBumpReceiver extends React.Component { render(){ return (
+ {/* Fist bump image is the button. Simulates the bump */} @@ -124,10 +170,19 @@ class WaitForBumpReceiver extends React.Component { TO INITIATE TRANSFER!
+ + {/* If currently downloading torrent, render loading spinner; else, render nothing */} + { this.state.showProgress + ?
Loading...
+ : null} + + {/* Container for the downloaded files */}
+ className="downloadListContainer container-fluid"> + + + {/* Cancel button (currently does not work) */} )} @@ -135,6 +190,7 @@ class WaitForBumpReceiver extends React.Component { // Declaring prop types WaitForBumpReceiver.propTypes = { + showProgress: PropTypes.bool, client: PropTypes.object, bumpCallback: PropTypes.func }; diff --git a/client/src/components/WaitForBumpSender.js b/client/src/components/WaitForBumpSender.js index defc48d..ec07c58 100644 --- a/client/src/components/WaitForBumpSender.js +++ b/client/src/components/WaitForBumpSender.js @@ -28,15 +28,13 @@ class WaitForBumpSender extends React.Component { - -
-

-
- FIST BUMP THE DEVICES -
- TO INITIATE TRANSFER! -

-
+ +

+
+ FIST BUMP THE DEVICES +
+ TO INITIATE TRANSFER! +

diff --git a/client/src/styles/containers.css b/client/src/styles/containers.css index 7ca07a4..9f5ccb6 100644 --- a/client/src/styles/containers.css +++ b/client/src/styles/containers.css @@ -18,6 +18,7 @@ ul{ padding: auto; } .fileListContainer{ + min-height: 200px; max-height: 200px; margin: auto; padding: auto; diff --git a/client/src/styles/transferinprogress.css b/client/src/styles/transferinprogress.css index a932e71..842914c 100644 --- a/client/src/styles/transferinprogress.css +++ b/client/src/styles/transferinprogress.css @@ -13,13 +13,13 @@ .text-style { font-family: 'Bangers', cursive; font-size: 36px; - margin-top: 50px; + margin-top: none; } /* credit to lukehaas for loading spinner*/ .loader { - color: #ebebeb; + color: #3b3b3b; font-size: 90px; text-indent: -9999em; overflow: hidden; diff --git a/client/src/styles/waitforbump.css b/client/src/styles/waitforbump.css index 3c74bf5..3209ca6 100644 --- a/client/src/styles/waitforbump.css +++ b/client/src/styles/waitforbump.css @@ -3,6 +3,7 @@ .text-style{ font-family: 'Bangers', cursive; font-size: 36px; + margin-top: none !important; } .fists-bumping-container { From 30a9aaeb536bba65f115bc0c628a2bf87745108a Mon Sep 17 00:00:00 2001 From: cngcruz Date: Fri, 20 May 2022 23:20:28 -0700 Subject: [PATCH 5/6] small css tweaking --- client/src/styles/containers.css | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/styles/containers.css b/client/src/styles/containers.css index 9f5ccb6..e687f6c 100644 --- a/client/src/styles/containers.css +++ b/client/src/styles/containers.css @@ -21,6 +21,7 @@ ul{ min-height: 200px; max-height: 200px; margin: auto; + margin-bottom: 1%; padding: auto; } .fileNameContainer{ From b37f4b39b2a0caf171b90bf6288174e91a494758 Mon Sep 17 00:00:00 2001 From: cngcruz Date: Sat, 21 May 2022 10:22:18 -0700 Subject: [PATCH 6/6] removing unnecessary code. fixing receive file list name bug. --- client/src/components/Home.js | 14 +--- client/src/components/ReceiveFiles.js | 108 -------------------------- client/src/styles/containers.css | 1 + 3 files changed, 2 insertions(+), 121 deletions(-) delete mode 100644 client/src/components/ReceiveFiles.js diff --git a/client/src/components/Home.js b/client/src/components/Home.js index 5f83e18..44ae940 100644 --- a/client/src/components/Home.js +++ b/client/src/components/Home.js @@ -39,18 +39,6 @@ class Home extends React.Component { console.log("Magnet Link: ", link); } - /** - * Called by ReceiveFiles when the user has pressed the "Receive" button. - * @param link: ReceiveFiles receives magnet link from db - */ - pressedReceiveButtonCallback = (link) => { - this.setState({ - appState: "ReadyToReceive", - magnetLink: link, - }); - console.log("Magnet Link: ", link); - } - /** * Called by WaitForBumpSender when a BAM/Bump has been detected * @param sensorData: Coordinates and Date sent by WaitForBumpSender @@ -73,7 +61,7 @@ class Home extends React.Component { * Called by WaitForBumpReceiver when a BAM/Bump has been detected * @param sensorData: Coordinates and Date received by WaitForBumpReceiver from db */ - receiveBumpCallback = (sensorData) => { + receiverBumpCallback = (sensorData) => { console.log("Sender BAM!", sensorData); // Build the API request body diff --git a/client/src/components/ReceiveFiles.js b/client/src/components/ReceiveFiles.js deleted file mode 100644 index ffe0236..0000000 --- a/client/src/components/ReceiveFiles.js +++ /dev/null @@ -1,108 +0,0 @@ -import '../styles/button.css' -import '../styles/index.css' -import 'bootstrap/dist/css/bootstrap.min.css' -import React from 'react' -import PropTypes from 'prop-types'; - -/** - * SendFiles handles all the sending files logic. - */ -class ReceiveFiles extends React.Component { - constructor(props) { - super(props); - this.state = { - files: null, - isChoosingFiles: true, - client: this.props.client, - } - } - - // Populates pre component with file names - handleFile = (e) => { - // Creating html components - e.preventDefault() - const fileListContainer = document.getElementById('fileListContainer') - const fileList = document.getElementById('filelist') - const userFiles = document.getElementById('files').files - - // Loop through userFiles and set html data to each file name - fileList.innerHTML = '' - for (let i = 0; i < userFiles.length; i++) { - fileList.innerHTML += userFiles[i].name + '\n\n' - } - - // If the list is empty, display nothing - // Else, display the html components - if (fileList.innerHTML === '' || fileList.innerHTML === null) { - fileList.style.display = 'none' - fileListContainer.style.display = 'none' - } else { - fileList.style.display = 'block' - fileListContainer.style.display = 'flex' - } - - // Set the current files state to userFiles - this.setState({ - files: userFiles - }); - } - - /** - * When the "Send Files" button is clicked, this function is called - */ - sendButtonClicked = () => { - // Files to send - console.log(this.state.files); - // Create torrent seed - let returnMagnetLink = this.props.pressedSendButtonCallback; - this.state.client.seed(this.state.files, function (torrent) { - // console.log("Client is seeding:\n" + torrent.magnetURI); - returnMagnetLink(torrent.magnetURI); - }); - - this.setState({ isChoosingFiles: false }); - } - - render() { - return ( -
-
-

-        
- - {/* Makes it so that when you click "Send", it un-renders the "Choose Files" and "Send" Button */} - {this.state.isChoosingFiles && ( -
- {/* File Choosing */} - - - {/* Send Files button */} - {/* Don't render "Send" Button if no files were chosen */} - {this.state.files && this.state.files.length > 0 && ( -
- -
- )} - -
- )} -
- ); - } -} - -// Declaring prop types -ReceiveFiles.propTypes = { - client: PropTypes.object, - pressedSendButtonCallback: PropTypes.func, -}; - -export default ReceiveFiles; diff --git a/client/src/styles/containers.css b/client/src/styles/containers.css index e687f6c..b03804e 100644 --- a/client/src/styles/containers.css +++ b/client/src/styles/containers.css @@ -26,6 +26,7 @@ ul{ } .fileNameContainer{ margin: 0; + overflow-wrap: break-word; } .downloadListContainer{ padding: 5%;