Files
adrive/templates/upload.html
Andrew ab84dea518
Some checks failed
Flask Run Test / Flask-Run-Test (push) Failing after 9s
show location of user
2026-01-10 20:07:23 +09:00

245 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADrive Share</title>
<script src="https://kit.fontawesome.com/972393379b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="app">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<!-- category: message, error, info, warning -->
{% if category == 'message' %}
{% set category = 'primary' %}
{% endif %}
{% if category == 'error' %}
{% set category = 'danger' %}
{% endif %}
{% if category == 'info' %}
{% set category = 'info' %}
{% endif %}
{% if category == 'warning' %}
{% set category = 'warning' %}
{% endif %}
<li class="alert alert-{{ category }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div class="form-section">
<form id="uploadForm" action="/sendfile" method="post" enctype="multipart/form-data">
{% if loggedIn %}
<h1>ADrive File Sharing <span class="badge text-bg-primary">{{ username }}</span></h1>
{% else %}
<h1>ADrive File Sharing <span class="badge text-bg-danger">Guest</span></h1>
{% endif %}
<!-- <span style="font-size: 20px;">
<i class="fa-solid fa-wifi fa-xs"
style="line-height: 25px; font-size: 15px; display: inline-block;"></i>
<span id="mirrorText">Ping: <span id="ping-value">CONNECTING</span>ms</span> <i
class="fa-solid fa-circle-dot fa-beat-fade fa-2xs" style="color: #ff9500;" id="mirrorLogo"></i>
</span> -->
<span style="font-size: 20px; padding-bottom: 7px;">
<i class="fa-solid fa-location fa-xs"
style="line-height: 25px; font-size: 15px; display: inline-block;"></i>
<span id="location-display" class="loading">Locating...</span> <i class="fa-solid fa-circle-dot fa-2xs" id="mirrorLogo" style="color: #c10101;"></i> <span class="badge text-bg-primary"><span id="ping-value">..</span>ms</span></span>
</span>
<input type="file" name="file" id="fileUpload" class="form-control" required aria-required>
<input type="hidden" id="quotaGB" value="{{ quota_gb }}">
<input type="hidden" id="quotaUsedGB" value="{{ quota_usage }}">
<div class="progress" id="uploadProgressContainer" style="display:none;width:100%;margin-top:8px">
<div id="uploadProgress" class="progress-bar bg-success" role="progressbar" style="width:0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
</div>
<div id="uploadProgressText" style="display:none;font-size:13px;margin-top:4px">0%</div>
<div class="input-group mb-3">
<div class="input-group-text">
<input class="form-check-input mt-0" type="checkbox" value="" id="reusableCheck" name="reusable"
aria-label="Checkbox for following text input" style="border: 1px solid rgb(106, 106, 106);">
<label for="reusable" style="margin-left: 6px; margin-bottom: 0;">Reusable
Link</label>
</div>
</div>
<input type="submit" class="" value="Upload" id="uploadBtn" onclick="uploadAnim()"
style="transition-duration: 400ms;">
</form>
<form>
<input type="text" class="form-control" id="codeInput">
<button type="button" value="Download" class="btn btn-primary" onclick="downloadClick()">Download</button>
</form>
{% if not loggedIn %}
<a href="/login" class="sign-in-button" style="text-decoration: none; background: rgb(0, 81, 139)">Sign
In</a>
<a href="/register" class="sign-in-button"
style="text-decoration: none; background: rgb(32, 0, 139)">Register</a><br><br>
<p style="color: gray; font-size: 11px; text-align: center;">Signing in is not required. You can at any time
register and sign in to manage your existing codes for free. You can manage up to 3GB of files.</p>
{% else %}
<a href="/dashboard" class="sign-in-button" style="text-decoration: none; background: blue">View
Dashboard</a>
<a href="/logout" class="sign-in-button" style="text-decoration: none; background: rgb(79, 92, 178)">Sign
Out</a>
{% endif %}
</div>
</div>
<script>
//document.getElementById("uploadBtn").addEventListener("click", uploadAnim);
function downloadClick() {
const codeEl = document.getElementById("codeInput");
const code = codeEl.value;
// clear input when clicked
codeEl.value = '';
const url = `/download/` + code;
location.href = url;
}
function uploadAnim(e) {
//if (document.getElementById("fileUpload").value == "") {
// document.getElementById("uploadBtn").classList.add("redBtn");
// document.getElementById("uploadBtn").value = "! ! !";
// e.preventDefault();
//} else {
// document.getElementById("uploadBtn").classList.add("yellowBtn");
// document.getElementById("uploadBtn").value = "· · ·";
//}
if (!document.getElementById("fileUpload").value == "") {
document.getElementById("uploadBtn").classList.add("yellowBtn");
document.getElementById("uploadBtn").value = "· · ·";
}
}
</script>
<script>
// Client-side quota check before uploading large files
(function () {
const fileInput = document.getElementById('fileUpload');
const uploadBtn = document.getElementById('uploadBtn');
const quotaGB = parseFloat(document.getElementById('quotaGB').value) || 0;
const usedGB = parseFloat(document.getElementById('quotaUsedGB').value) || 0;
const remainingGB = Math.max(0, quotaGB - usedGB);
function ensureFlashesContainer() {
let flashes = document.querySelector('.flashes');
if (!flashes) {
flashes = document.createElement('ul');
flashes.className = 'flashes';
const app = document.querySelector('.app');
if (app) app.insertBefore(flashes, app.firstChild);
}
return flashes;
}
function clearClientFlash() {
const flashes = document.querySelectorAll('.flashes li.client-quota-warning');
flashes.forEach(n => n.remove());
}
function showClientFlash(message) {
clearClientFlash();
const flashes = ensureFlashesContainer();
const li = document.createElement('li');
li.className = 'warning client-quota-warning';
const strong = document.createElement('strong');
strong.textContent = message;
li.appendChild(strong);
flashes.prepend(li);
}
if (fileInput) {
fileInput.addEventListener('change', function (e) {
clearClientFlash();
uploadBtn.disabled = false;
const f = fileInput.files && fileInput.files[0];
if (!f) return;
const fileGB = f.size / (1024 * 1024 * 1024);
if (fileGB > remainingGB) {
showClientFlash('You do not have sufficient quota to manage this file. If you choose to upload this file, you will not be able to manage it through your dashboard.');
// still allow upload; server will accept but will not set owner when quota insufficient
} else {
clearClientFlash();
}
});
}
})();
</script>
<script>
function measurePing() {
const start = Date.now();
fetch('/ping')
.then(() => {
const end = Date.now();
const latency = end - start;
document.getElementById('ping-value').innerText = latency;
})
.catch(err => {
document.getElementById('ping-value').innerText = "Error";
});
}
document.getElementById("fileUpload").disabled = true;
document.getElementById("uploadBtn").disabled = true;
document.getElementById("codeInput").disabled = true;
document.getElementById("reusableCheck").disabled = true;
// Measure ping immediately on load
setTimeout(() => {
document.getElementById("mirrorLogo").classList.remove("fa-beat-fade");
document.getElementById("mirrorLogo").style.color = "green";
measurePing();
document.getElementById("fileUpload").disabled = false;
document.getElementById("codeInput").disabled = false;
document.getElementById("uploadBtn").disabled = false;
document.getElementById("reusableCheck").disabled = false;
}, 1000);
setInterval(() => {
measurePing();
}, 1000); // Update every 30 seconds
</script>
<script>
async function loadLocation() {
try {
const response = await fetch('/get-location');
const data = await response.json();
if (data.status === 'success') {
document.getElementById('location-display').innerHTML =
`${data.city}, ${data.country} <small>(${data.isp})</small>`;
document.getElementById('location-display').classList.remove('loading');
} else {
throw new Error();
}
} catch (err) {
document.getElementById('location-display').innerText = "Unknown Location";
}
}
loadLocation();
</script>
<script src="{{ url_for('static', filename='script.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous"></script>
</body>
</html>