Created
March 9, 2020 17:55
-
-
Save evalphobia/f24a318973bda5a28c1755171a5bb89e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(() => { | |
// initialize app | |
function init() { | |
_firebaseInit() | |
_firebaseAuthInit() | |
} | |
function _(el) { | |
return document.getElementById(el); | |
} | |
// initialize firebase | |
function _firebaseInit() { | |
// Your web app's Firebase configuration | |
var firebaseConfig = { | |
apiKey: "<your own data here>", | |
authDomain: "<your own data here>", | |
databaseURL: "<your own data here>", | |
projectId: "<your own data here>", | |
storageBucket: "<your own data here>", | |
messagingSenderId: "<your own data here>", | |
appId: "<your own data here>" | |
}; | |
// Initialize Firebase | |
firebase.initializeApp(firebaseConfig); | |
} | |
// initialize firebase auth via firebase-ui | |
function _firebaseAuthInit() { | |
var ui = new firebaseui.auth.AuthUI(firebase.auth()); | |
var uiConfig = { | |
callbacks: { | |
signInSuccessWithAuthResult: function(authResult, redirectUrl) { | |
_('did-login').style.display = 'block'; | |
_('non-login').style.display = 'none'; | |
fetchFileListAndUpdateListView() | |
return false; | |
}, | |
uiShown: function() { | |
_('loader').style.display = 'none'; | |
} | |
}, | |
signInFlow: 'popup', | |
signInOptions: [ | |
firebase.auth.GoogleAuthProvider.PROVIDER_ID, | |
], | |
}; | |
ui.start('#firebaseui-auth-container', uiConfig); | |
} | |
//======================== | |
// read data from Storage | |
//======================== | |
const storagePrefix = 'uploaded_items/' | |
function fetchFileListAndUpdateListView() { | |
const listRef = firebase.storage().ref(storagePrefix); | |
let results = []; | |
listRef.listAll().then(res => { | |
res.items.forEach(itemRef => { | |
const path = itemRef.fullPath.replace(storagePrefix, '') | |
results.push(path) | |
}); | |
updateListView(results) | |
}).catch(err => { | |
console.warn(`error on list: ${err}`) | |
}); | |
} | |
function updateListView(list) { | |
// remove all list | |
const el = _("uploaded-data-list") | |
el.textContent = null; | |
while (el.firstChild) el.removeChild(el.firstChild); | |
// create new list | |
let fragment = document.createDocumentFragment(); | |
list.forEach(item => { | |
// naming convention must be `{date}__{username}__{filename}` | |
// (e.g.) `2020-03-05__evalphobia__my_awesome_movie-01.mp4` | |
const parts = item.split('__') | |
const date = parts[0] | |
const user = parts[1] | |
const path = parts[2] | |
const td1 = document.createElement('td'); | |
td1.appendChild(document.createTextNode(date)) | |
const td2 = document.createElement('td'); | |
td2.appendChild(document.createTextNode(user)) | |
const td3 = document.createElement('td'); | |
td3.appendChild(document.createTextNode(path)) | |
const tr = document.createElement('tr'); | |
tr.appendChild(td1) | |
tr.appendChild(td2) | |
tr.appendChild(td3) | |
fragment.appendChild(tr); | |
}) | |
// add the list | |
el.appendChild(fragment) | |
} | |
//======================== | |
// write data to Storage | |
//======================== | |
const input = _('fileinput'); | |
input.addEventListener("change", ev => { | |
const f = ev.target.files; | |
if (!f || f.length != 1) { | |
return | |
} | |
uploadFile(f) | |
}) | |
function uploadFile(files) { | |
const file = files[0] | |
const fileName = getFileName(file) | |
displayFileName(fileName) | |
const storageRef = firebase.storage().ref(storagePrefix); | |
const uploadRef = storageRef.child(fileName); | |
const blob = new Blob(files, { type: file.type }); | |
const uploadTask = uploadRef.put(blob) // file is uploading here! | |
uploadTask.on('state_changed', snapshot => { | |
// uploading... | |
const percent = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; | |
_("progressBar").value = Math.round(percent); | |
_("progressStatus").innerHTML = Math.round(percent) + "% uploaded..."; | |
}, err => { | |
// error occors when uploading... | |
alert("Failed to upload the file") | |
completeProgress() | |
}, () => { | |
// After the upload task... | |
alert("Upload Complete!") | |
completeProgress() | |
}) | |
} | |
function getFileName(file) { | |
// get user name | |
const user = firebase.auth().currentUser; | |
let userName = user.email.split('@')[0]; | |
if (!userName) { | |
// Don't allow empty email address user. | |
alert("Upload failed...") | |
location.reload() | |
return | |
} | |
// if the file name already contains double underscore, change to single. | |
const baseName = file.name.replace('__', '_') | |
userName = 'evalphovia' | |
const fileName = `${_getYYYYMMDD(new Date())}__${userName}__${baseName}` | |
return fileName | |
} | |
function _getYYYYMMDD(dt) { | |
const yyyy = dt.getFullYear(); | |
const mm = ("00" + (dt.getMonth()+1)).slice(-2); | |
const dd = ("00" + dt.getDate()).slice(-2); | |
return `${yyyy}-${mm}-${dd}` | |
} | |
// clear input form and reload uploaded file list | |
function completeProgress() { | |
_("fileinput").disabled = ''; | |
_("fileinput").value = ''; | |
_("progressBar").value = 0; | |
_("progressStatus").innerHTML = '' | |
fetchFileListAndUpdateListView() | |
clearFileName() | |
} | |
// update display and refuse file upload | |
function displayFileName(name) { | |
const el = _("filename") | |
el.value = name | |
el.style.display = 'inline-block'; | |
_("fileinput").disabled = true; | |
} | |
// clear display and accept file upload | |
function clearFileName(name) { | |
const el = _("filename") | |
el.value = '' | |
el.style.display = 'none'; | |
_("fileinput").disabled = ''; | |
} | |
init() | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Welcome</title> | |
<!-- update the version number as needed --> | |
<script defer src="/__/firebase/7.9.3/firebase-app.js"></script> | |
<!-- include only the Firebase features as you need --> | |
<script defer src="/__/firebase/7.9.3/firebase-auth.js"></script> | |
<script defer src="/__/firebase/7.9.3/firebase-storage.js"></script> | |
<script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.js"></script> | |
<!-- <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth__{lang}.js"></script> --> | |
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" /> | |
<!-- initialize the SDK after all desired features are loaded --> | |
<script src="https://www.gstatic.com/firebasejs/7.9.3/firebase.js"></script> | |
<script defer src="/__/firebase/init.js"></script> | |
</head> | |
<body> | |
<!-- #01 --> | |
<section id="non-login" class="container""> | |
<h2>Please login, then you can upload file. </h2> | |
<br /> | |
<div id="loader">Firebase SDK Loading…</div> | |
<div id="firebaseui-auth-container"></div> | |
</section> | |
<!-- #02 --> | |
<section id="did-login" class="container" style="display: none;"> | |
<div id="upload-form" class="upload-form"> | |
<div class="upload-button"> | |
Choose file | |
<input type="file" name="fileinput" id="fileinput" /> | |
<input type="text" id="filename" class="filename" disabled /> | |
</div> | |
<br /> | |
<progress id="progressBar" class="progressbar" value="0" max="100"></progress> | |
<p id="progressStatus" class="progress-status"></p> | |
</div> | |
<hr /> | |
<div id="uploaded-data"> | |
<h3>Uploaded File List</h2> | |
<table class="list-table"> | |
<thead> | |
<tr> | |
<th>Date</th> | |
<th>User</th> | |
<th>File</th> | |
</th> | |
</thead> | |
<tbody id="uploaded-data-list"></tbody> | |
</table> | |
<ul class="file-list"> | |
</ul> | |
</div> | |
</section> | |
<script src="app.js"></script> | |
<style media="screen"> | |
body { | |
background: #ECEFF1; | |
min-height: 100vh; | |
color: rgba(0,0,0,0.87); | |
margin: 0; | |
padding: 0; | |
} | |
.container { | |
background: white; max-width: 380px; margin: 100px auto 16px; padding: 32px 24px; border-radius: 3px; | |
} | |
.container h2 { | |
color: #333333; | |
font-weight: bold; | |
font-size: 16px; | |
margin: 0 0 8px; | |
} | |
.upload-form { | |
text-align: center; | |
} | |
.progressbar { | |
width: 150px; | |
} | |
.progress-status { | |
margin-top: 0px; | |
} | |
.upload-button { | |
display: inline-block; | |
position: relative; | |
overflow: hidden; | |
border-radius: 3px; | |
background: #3388cc; | |
color: #ffffff; | |
text-align: center; | |
padding: 10px; | |
line-height: 30px; | |
width: 180px; | |
cursor: pointer; | |
} | |
.upload-button:hover { | |
background: #4499dd; | |
} | |
.upload-button input[type=file] { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
cursor: pointer; | |
opacity: 0; | |
} | |
.filename { | |
display: none; | |
background: rgba(255,255,255,0.2); | |
border-radius: 3px; | |
padding: 3px; | |
color: #ffffff; | |
} | |
.list-table { | |
border: #ECEFF1 solid 1px; | |
border-collapse: collapse; | |
border-spacing: 8px 2px; | |
} | |
.list-table tbody { | |
border-top: #ECEFF1 solid 1px; | |
} | |
.list-table th, td { | |
padding: 2px; | |
border-left: #ECEFF1 solid 1px; | |
border-right: #ECEFF1 solid 1px; | |
} | |
</style> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment