0.8.9: Better frontend and idk what more

This commit is contained in:
Fijxu 2024-08-22 18:59:08 -04:00
parent 69fe5a3c58
commit 7ee5956970
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
6 changed files with 382 additions and 278 deletions

View file

@ -1,20 +1,21 @@
// By chatgpt becuase I hate frontend and javascript kill me
document.addEventListener("DOMContentLoaded", () => {
const dropArea = document.getElementById("drop-area");
const fileInput = document.getElementById("fileElem");
const uploadStatus = document.getElementById("upload-status");
// Prevent default drag behaviors
["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => {
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
// Highlight drop area when item is dragged over
["dragenter", "dragover"].forEach(eventName => {
["dragenter", "dragover"].forEach((eventName) => {
dropArea.addEventListener(eventName, highlight, false);
});
["dragleave", "drop"].forEach(eventName => {
["dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, unhighlight, false);
});
@ -23,10 +24,14 @@ document.addEventListener("DOMContentLoaded", () => {
dropArea.addEventListener("click", () => fileInput.click());
// Handle file selection
fileInput.addEventListener("change", () => {
fileInput.addEventListener(
"change",
() => {
const files = fileInput.files;
handleFiles(files);
}, false);
},
false
);
// Handle pasted files
document.addEventListener("paste", handlePaste, false);
@ -77,20 +82,28 @@ document.addEventListener("DOMContentLoaded", () => {
const uploadContainer = document.createElement("div");
const statusLink = document.createElement("div");
const uploadText = document.createElement("span");
const buttons = document.createElement("div");
const copyButton = document.createElement("button");
const deleteButton = document.createElement("button");
uploadContainer.className = "upload-status"; // Use the existing CSS class for styling
uploadContainer.appendChild(uploadText);
uploadContainer.appendChild(statusLink);
uploadContainer.appendChild(copyButton);
uploadStatus.appendChild(uploadContainer); // Append to the main upload status container
buttons.appendChild(copyButton)
buttons.appendChild(deleteButton)
uploadContainer.appendChild(buttons)
uploadStatus.appendChild(uploadContainer);
// Update upload text
uploadText.innerHTML = "0%";
uploadText.className = "percent"
uploadText.className = "percent";
statusLink.className = "status";
copyButton.className = "copy-button"; // Add class for styling
copyButton.innerHTML = "Copiar"; // Set button text
copyButton.style.display = "none"; // Hide initially
deleteButton.className = "delete-button";
deleteButton.innerHTML = "Borrar";
copyButton.style.display = "none";
deleteButton.style.display = "none";
// Update progress text
xhr.upload.addEventListener("progress", (e) => {
@ -100,28 +113,41 @@ document.addEventListener("DOMContentLoaded", () => {
}
});
// Handle response
xhr.onerror = () => {
console.error("Error:", xhr.status, xhr.statusText, xhr.responseText);
statusLink.textContent = "Error desconocido";
};
xhr.onload = () => {
// console.log("Response Status:", xhr.status);
// console.log("Response Text:", xhr.responseText);
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
const fileLink = response.link; // Assuming the response contains a key 'link'
const fileLink = response.link;
statusLink.innerHTML = `<a href="${fileLink}" target="_blank">${fileLink}</a>`;
copyButton.style.display = "inline"; // Show the copy button
copyButton.onclick = () => copyToClipboard(fileLink); // Set the copy action
copyButton.style.display = "inline";
copyButton.onclick = () => copyToClipboard(fileLink);
deleteButton.style.display = "inline";
deleteButton.onclick = () => {
window.open(response.deleteLink, "_blank");
};
} catch (error) {
statusLink.textContent = "File uploaded but failed to parse response.";
statusLink.textContent =
"Error desconocido, habla con el administrador";
}
} else if (xhr.status >= 400 && xhr.status < 500) {
try {
const errorResponse = JSON.parse(xhr.responseText);
statusLink.textContent = errorResponse.error || "Error del cliente.";
} catch (e) {
statusLink.textContent = "Error del cliente.";
}
} else {
statusLink.textContent = "File upload failed.";
statusLink.textContent = "Error del servidor.";
}
};
// Handle errors
xhr.onerror = () => {
statusLink.textContent = "An error occurred during the file upload.";
};
// Send file
const formData = new FormData();
formData.append("file", file);
@ -131,9 +157,12 @@ document.addEventListener("DOMContentLoaded", () => {
// Function to copy the link to the clipboard
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
navigator.clipboard
.writeText(text)
.then(() => {
// alert("Link copied to clipboard!"); // Notify the user
}).catch(err => {
})
.catch((err) => {
console.error("Failed to copy: ", err);
});
}

View file

@ -9,6 +9,7 @@
font-weight: 900;
src: url('frahv.ttf');
}
@font-face {
font-family: "XFG";
font-weight: 900;
@ -22,8 +23,11 @@ html {
rgba(11, 11, 11, 0.92)),
url(./bliss-small.avif);
background-attachment: fixed;
background-repeat: no-repeat;
background-size: cover;
}
body {
/* font-family: Arial, sans-serif; */
/* background-color: #111; */
@ -31,7 +35,12 @@ body {
padding: 20px;
}
p, h1, h2, h3, h4, h5 {
p,
h1,
h2,
h3,
h4,
h5 {
color: aliceblue
}
@ -62,7 +71,7 @@ a {
}
.container {
max-width: 700px;
max-width: 800px;
margin: auto;
/* background: white; */
/*! padding: 20px; */
@ -79,8 +88,10 @@ a {
text-align: center;
position: relative;
width: fit-content;
margin: 0 auto; /* Center the element */
display: block; /* Ensure it behaves as a block-level element */
margin: 0 auto;
/* Center the element */
display: block;
/* Ensure it behaves as a block-level element */
background: rgba(202, 230, 190, .75);
border: 1px solid #b7d1a0;
border-radius: 4px;
@ -107,8 +118,8 @@ a {
margin-top: 10px;
}
nav a, nav > ul
{
nav a,
nav>ul {
list-style: none;
margin: 0;
padding: 0;
@ -116,47 +127,92 @@ nav a, nav > ul
}
#upload-status {
margin: 20px; /* Adjust as needed */
margin: 20px;
/* Adjust as needed */
}
.upload-status {
display: flex;
align-items: center;
justify-content: space-between;
border: 2px solid #999; /* Optional styling for the status box */
padding: 5px; /* Optional padding */
/*! border-radius: 6px; */ /* Optional rounded corners */
/*! background-color: #f9f9f9; */ /* Optional background color */
border: 2px solid #999;
/* Optional styling for the status box */
padding: 5px;
/* Optional padding */
/*! border-radius: 6px; */
/* Optional rounded corners */
/*! background-color: #f9f9f9; */
/* Optional background color */
}
.link-container {
display: flex;
align-items: center;
margin-left: auto; /* Pushes the link and button to the right */
margin-left: auto;
/* Pushes the link and button to the right */
}
.link {
color: #ffb6c1;
text-decoration: none; /* Remove underline from link */
margin-right: 5px; /* Space between link and button */
text-decoration: none;
/* Remove underline from link */
margin-right: 5px;
/* Space between link and button */
}
.link:hover {
text-decoration: underline; /* Optional: underline on hover */
text-decoration: underline;
/* Optional: underline on hover */
}
.copy-button {
display: inline;
background-color: #5e5e5e; /* Button background color */
color: white; /* Button text color */
border: none; /* Remove border */
border-radius: 3px; /* Rounded corners for the button */
padding: 5px 10px; /* Button padding */
cursor: pointer; /* Pointer cursor on hover */
background-color: #7a6fff;
/* Button background color */
color: white;
/* Button text color */
border: none;
/* Remove border */
border-radius: 3px;
/* Rounded corners for the button */
padding: 5px 10px;
/* Button padding */
cursor: pointer;
/* Pointer cursor on hover */
font-weight: bold;
}
.delete-button {
display: inline;
background-color: #ff6f6f;
/* Button background color */
color: white;
/* Button text color */
border: none;
/* Remove border */
border-radius: 3px;
/* Rounded corners for the button */
padding: 5px 10px;
/* Button padding */
cursor: pointer;
/* Pointer cursor on hover */
margin-left: 6px;
font-weight: bold;
}
.copy-button:hover {
background-color: #404040; /* Darker shade on hover */
background-color: #6057ce;
/* Darker shade on hover */
}
.delete-button:hover {
background-color: #ce5757;
/* Darker shade on hover */
}
.status {
color: rgb(255, 132, 0);
}
a:link {

View file

@ -20,6 +20,8 @@ module Jobs
spawn do
loop do
Utils.retrieve_tor_exit_nodes
# Updates the @@exit_nodes array instantly
Routing.reload_exit_nodes
sleep CONFIG.torExitNodesCheck
end
end
@ -28,9 +30,7 @@ module Jobs
def self.kemal
spawn do
if !CONFIG.unix_socket.nil?
Kemal.run do |config|
config.server.not_nil!.bind_unix "#{CONFIG.unix_socket}"
end
Kemal.run &.server.not_nil!.bind_unix "#{CONFIG.unix_socket}"
else
Kemal.run
end

View file

@ -3,19 +3,10 @@ require "./http-errors"
module Routing
extend self
@@exit_nodes = Array(String).new
if CONFIG.blockTorAddresses
spawn do
# Wait a little for Utils.retrieve_tor_exit_nodes to execute first
# or it will load an old exit node list
# I think this can be replaced by channels which makes me able to
# receive data from fibers
sleep 5
loop do
def reload_exit_nodes
LOGGER.debug "Updating Tor exit nodes array"
@@exit_nodes = Utils.load_tor_exit_nodes
sleep CONFIG.torExitNodesCheck + 5
end
end
end
before_post "/api/admin/*" do |env|
@ -86,11 +77,12 @@ module Routing
Handling.sharex_config(env)
end
if CONFIG.adminEnabled
self.register_admin
end
end
def register_admin
if CONFIG.adminEnabled
# post "/api/admin/upload" do |env|
# Handling::Admin.delete_ip_limit(env)
# end
@ -98,8 +90,8 @@ module Routing
Handling::Admin.delete_file(env)
end
end
post "/api/admin/deleteiplimit" do |env|
Handling::Admin.delete_ip_limit(env)
end
end
end

View file

@ -135,7 +135,8 @@ module Utils
end
end
# Delete socket if the server has not been previously cleaned by the server (Due to unclean exits, crashes, etc.)
# Delete socket if the server has not been previously cleaned by the server
# (Due to unclean exits, crashes, etc.)
def delete_socket
if File.exists?("#{CONFIG.unix_socket}")
LOGGER.info "Deleting old unix socket"
@ -167,21 +168,43 @@ module Utils
msg("File '#{fileinfo[:filename]}' deleted successfully")
end
def detect_extension(file) : String
magic_bytes = {
MAGIC_BYTES = {
# Images
".png" => "89504e470d0a1a0a",
".heic" => "6674797068656963",
".jpg" => "ffd8ff",
".webm" => "1a45dfa3",
".mp4" => "66747970",
".gif" => "474946383",
# Videos
".mp4" => "66747970",
".webm" => "1a45dfa3",
".mov" => "6d6f6f76",
".wmv" => "󠀀3026b2758e66cf11",
".flv" => "󠀀464c5601",
".mpeg" => "000001bx",
# Audio
".mp3" => "󠀀494433",
".aac" => "󠀀fff1",
".wav" => "󠀀57415645666d7420",
".flac" => "󠀀664c614300000022",
".ogg" => "󠀀4f67675300020000000000000000",
".wma" => "󠀀3026b2758e66cf11a6d900aa0062ce6c",
".aiff" => "󠀀464f524d00",
# Whatever
".7z" => "377abcaf271c",
".gz" => "1f8b",
".iso" => "󠀀4344303031",
# Documents
"pdf" => "󠀀25504446",
"html" => "<!DOCTYPE html>",
}
def detect_extension(file) : String
file = File.open(file)
slice = Bytes.new(8)
slice = Bytes.new(16)
hex = IO::Hexdump.new(file)
# Reads the first 16 bytes of the file in Heap
hex.read(slice)
magic_bytes.each do |ext, mb|
MAGIC_BYTES.each do |ext, mb|
if slice.hexstring.includes?(mb)
return ext
end
@ -191,18 +214,22 @@ module Utils
def retrieve_tor_exit_nodes
LOGGER.debug "Retrieving Tor exit nodes list"
resp = HTTP::Client.get(CONFIG.torExitNodesUrl) do |res|
HTTP::Client.get(CONFIG.torExitNodesUrl) do |res|
begin
if res.success? && res.status_code == 200
begin
File.open(CONFIG.torExitNodesFile, "w") do |output|
IO.copy(res.body_io, output)
end
File.open(CONFIG.torExitNodesFile, "w") { |output| IO.copy(res.body_io, output) }
rescue ex
LOGGER.error "Failed to write to file: #{ex.message}"
end
else
LOGGER.error "Failed to retrieve exit nodes list. Status Code: #{res.status_code}"
end
rescue ex : Socket::ConnectError
LOGGER.error "Failed to connect to #{CONFIG.torExitNodesUrl}: #{ex.message}"
rescue ex
LOGGER.error "Unknown error: #{ex.message}"
end
end
end