ctrl + v when file modal is open and drag file to instantly upload
This commit is contained in:
parent
fa373d6b46
commit
29e26aa647
12
app.py
12
app.py
@ -668,17 +668,23 @@ def shorten_url():
|
||||
return jsonify({'success': False, 'error': 'URL is required'}), 400
|
||||
|
||||
long_url = data['url']
|
||||
password = data.get('password') # Get the password if provided
|
||||
vanity = shortuuid.uuid()[:8]
|
||||
|
||||
user_id = current_user.id if current_user.is_authenticated else None
|
||||
|
||||
db = get_db()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("INSERT INTO content (vanity, type, data, created_at, user_id) VALUES (?, ?, ?, ?, ?)",
|
||||
(vanity, 'url', long_url, datetime.now(), user_id))
|
||||
|
||||
is_private = 1 if password else 0
|
||||
|
||||
cursor.execute("""
|
||||
INSERT INTO content (vanity, type, data, created_at, user_id, is_private, password)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""", (vanity, 'url', long_url, datetime.now(), user_id, is_private, password))
|
||||
|
||||
db.commit()
|
||||
|
||||
# Return only the vanity code, not the full URL
|
||||
return jsonify({'success': True, 'vanity': vanity}), 200
|
||||
except Exception as e:
|
||||
print("Exception occurred:", str(e))
|
||||
|
@ -66,7 +66,13 @@
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
<p>Source code on: </p><a href="https://github.com/realcgcristi/aCloud" target="_blank">GitHub</a> | <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a>
|
||||
<div class="footer">
|
||||
<p>
|
||||
Source code on: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -258,6 +258,40 @@
|
||||
.other-links.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.global-drop-area {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 9999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.global-drop-box {
|
||||
border: 3px dashed #4CAF50;
|
||||
border-radius: 20px;
|
||||
padding: 50px;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.instant-upload-result {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #2a2a2a;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
z-index: 10000;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -329,15 +363,37 @@
|
||||
<span class="close" onclick="closeModal('urlModal')">×</span>
|
||||
<h2>Shorten URL</h2>
|
||||
<input type="text" id="urlInput" placeholder="Enter URL here...">
|
||||
<div>
|
||||
<input type="checkbox" id="urlIsPrivate" name="urlIsPrivate">
|
||||
<label for="urlIsPrivate">Add password protection</label>
|
||||
</div>
|
||||
<div id="urlPasswordField" style="display: none;">
|
||||
<input type="password" id="urlPassword" placeholder="Enter password">
|
||||
</div>
|
||||
<button onclick="shortenUrl()">Shorten URL</button>
|
||||
<div id="urlResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="global-drop-area">
|
||||
<div class="global-drop-box">
|
||||
<h2>Drop file to instantly upload</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="instant-upload-result">
|
||||
<h3>File Uploaded</h3>
|
||||
<p>Direct download URL: <a id="directDownloadUrl" href="#" target="_blank"></a></p>
|
||||
<p>Normal URL: <a id="normalUrl" href="#" target="_blank"></a></p>
|
||||
<button onclick="closeInstantUploadResult()">Close</button>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<p>Source code available on:
|
||||
<a href="https://github.com/realcgcristi/order" target="_blank">GitHub (not up-to-date)</a> |
|
||||
<a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git (main)</a>
|
||||
|
||||
<a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git (main)</a> |
|
||||
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
@ -433,6 +489,10 @@
|
||||
document.getElementById('filePasswordField').style.display = this.checked ? 'block' : 'none';
|
||||
});
|
||||
|
||||
document.getElementById('urlIsPrivate').addEventListener('change', function() {
|
||||
document.getElementById('urlPasswordField').style.display = this.checked ? 'block' : 'none';
|
||||
});
|
||||
|
||||
function uploadText() {
|
||||
const content = document.getElementById('textContent').value;
|
||||
const isPrivate = document.getElementById('isPrivate').checked;
|
||||
@ -608,13 +668,20 @@
|
||||
|
||||
function shortenUrl() {
|
||||
const url = document.getElementById('urlInput').value;
|
||||
const isPrivate = document.getElementById('urlIsPrivate').checked;
|
||||
const password = isPrivate ? document.getElementById('urlPassword').value : null;
|
||||
|
||||
const data = {
|
||||
url: url,
|
||||
password: password
|
||||
};
|
||||
|
||||
fetch('/shorten', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ url: url }),
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
@ -625,7 +692,11 @@
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const shortUrl = `${window.location.origin}/${data.vanity}`;
|
||||
document.getElementById('urlResult').innerHTML = `URL shortened. Access it <a href="${shortUrl}" target="_blank">${shortUrl}</a>`;
|
||||
let resultHtml = `URL shortened. Access it <a href="${shortUrl}" target="_blank">${shortUrl}</a>`;
|
||||
if (isPrivate) {
|
||||
resultHtml += `<br>Password-protected link: <a href="${shortUrl}/${password}" target="_blank">${shortUrl}/${password}</a>`;
|
||||
}
|
||||
document.getElementById('urlResult').innerHTML = resultHtml;
|
||||
} else {
|
||||
document.getElementById('urlResult').innerHTML = `Error: ${data.error}`;
|
||||
}
|
||||
@ -635,6 +706,70 @@
|
||||
document.getElementById('urlResult').innerHTML = `An error occurred: ${error.message}`;
|
||||
});
|
||||
}
|
||||
|
||||
// Global drag and drop
|
||||
document.addEventListener('dragover', function(e) {
|
||||
e.preventDefault();
|
||||
document.querySelector('.global-drop-area').style.display = 'flex';
|
||||
});
|
||||
|
||||
document.addEventListener('dragleave', function(e) {
|
||||
if (e.clientX === 0 || e.clientY === 0) {
|
||||
document.querySelector('.global-drop-area').style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('drop', function(e) {
|
||||
e.preventDefault();
|
||||
document.querySelector('.global-drop-area').style.display = 'none';
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
instantUploadFile(e.dataTransfer.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
function instantUploadFile(file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
fetch('/upload/file', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
document.getElementById('directDownloadUrl').href = data.download_url;
|
||||
document.getElementById('directDownloadUrl').textContent = data.download_url;
|
||||
document.getElementById('normalUrl').href = data.url;
|
||||
document.getElementById('normalUrl').textContent = data.url;
|
||||
document.querySelector('.instant-upload-result').style.display = 'block';
|
||||
} else {
|
||||
alert('Error uploading file: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred while uploading the file');
|
||||
});
|
||||
}
|
||||
|
||||
function closeInstantUploadResult() {
|
||||
document.querySelector('.instant-upload-result').style.display = 'none';
|
||||
}
|
||||
|
||||
// Paste functionality for file upload
|
||||
document.addEventListener('paste', function(e) {
|
||||
if (document.getElementById('fileModal').style.display === 'block') {
|
||||
const items = e.clipboardData.items;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].kind === 'file') {
|
||||
const file = items[i].getAsFile();
|
||||
filesToUpload.push(file);
|
||||
updateSelectedFilesList();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -11,12 +11,17 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: #1a1a1a;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.container {
|
||||
background-color: #2a2a2a;
|
||||
padding: 20px;
|
||||
@ -75,27 +80,54 @@
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.back-button {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
font-size: 24px;
|
||||
color: #4CAF50;
|
||||
text-decoration: none;
|
||||
}
|
||||
.back-button:hover {
|
||||
color: #45a049;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
background-color: #2a2a2a;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Login</h2>
|
||||
<form method="POST">
|
||||
<div>
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="remember-me">
|
||||
<input type="checkbox" id="remember" name="remember">
|
||||
<label for="remember">Remember me</label>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<p>Don't have an account? <a href="{{ url_for('register') }}">Register here</a></p>
|
||||
<a href="/" class="back-button">←</a>
|
||||
<div class="content">
|
||||
<div class="container">
|
||||
<h2>Login</h2>
|
||||
<form method="POST">
|
||||
<div>
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="remember-me">
|
||||
<input type="checkbox" id="remember" name="remember">
|
||||
<label for="remember">Remember me</label>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<p>Don't have an account? <a href="{{ url_for('register') }}">Register here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<p>
|
||||
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
@ -185,10 +185,25 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
.home-button {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
font-size: 24px;
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.home-button:hover {
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
{{ css|safe }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="/" class="home-button">⌂</a>
|
||||
<div class="container">
|
||||
<h2>Content</h2>
|
||||
<p>Uploaded by: {{ content.username }}</p>
|
||||
@ -229,6 +244,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer style="text-align: center; margin-top: 20px; padding: 10px; background-color: #2a2a2a; color: #f0f0f0;">
|
||||
<p>
|
||||
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
const rawContent = {{ raw_content|tojson }};
|
||||
|
||||
|
@ -11,12 +11,17 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: #1a1a1a;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.container {
|
||||
background-color: #2a2a2a;
|
||||
padding: 20px;
|
||||
@ -67,23 +72,50 @@
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.back-button {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
font-size: 24px;
|
||||
color: #4CAF50;
|
||||
text-decoration: none;
|
||||
}
|
||||
.back-button:hover {
|
||||
color: #45a049;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
background-color: #2a2a2a;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Register</h2>
|
||||
<form method="POST">
|
||||
<div>
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<p>Already have an account? <a href="{{ url_for('login') }}">Login here</a></p>
|
||||
<a href="/" class="back-button">←</a>
|
||||
<div class="content">
|
||||
<div class="container">
|
||||
<h2>Register</h2>
|
||||
<form method="POST">
|
||||
<div>
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<p>Already have an account? <a href="{{ url_for('login') }}">Login here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<p>
|
||||
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user