Updated 10 files and added 4 files (automated)

mane
Mia Raindrops 2 weeks ago
parent 7348d637ca
commit af1fb5ecf1
Signed by: Mia Raindrops
GPG Key ID: EFBDC68435A574B7

@ -61,21 +61,26 @@ if (!isset($id)):
<?= doLinking($data["contents"]) ?>
</div>
<small class="print-ignore text-muted"><?= isset($data["update_user"]) ? str_replace("%2", "<a class='update-user' href='/profile/" . $data["update_user"] . "'>" . resolveUser($data["update_user"]) . "</a>", str_replace("%1", timeAgo($data["update"]), l("lang_time_update_user"))) : str_replace("%1", timeAgo($data["update"]), l("lang_time_update")) ?></small>
<?php endif; ?>
<?php endif;
$images = $data["images"];
shuffle($images);
?>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;">
<div>
<?php $index = 1; foreach ($data["images"] as $image): if ($index % 3 === 1): ?>
<?php $index = 1; foreach ($images as $image): if ($index % 3 === 1): ?>
<a href="#" onclick="showGalleryItem(<?= $index ?>);"><img id="gallery-item-<?= $index ?>" title="<?= l("lang_gallery_uploader") . " " . resolveUser($image["author"]) . " " . timeAgo($image["date"]) ?>" src="/uploads/<?= $image["id"] ?>.webp" style="width: 100%; margin-top: 20px; border-radius: 10px;" data-bs-toggle="tooltip"></a>
<?php endif; $index++; endforeach; ?>
</div>
<div>
<?php $index = 1; foreach ($data["images"] as $image): if ($index % 3 === 2): ?>
<?php $index = 1; foreach ($images as $image): if ($index % 3 === 2): ?>
<a href="#" onclick="showGalleryItem(<?= $index ?>);"><img id="gallery-item-<?= $index ?>" title="<?= l("lang_gallery_uploader") . " " . resolveUser($image["author"]) . " " . timeAgo($image["date"]) ?>" src="/uploads/<?= $image["id"] ?>.webp" style="width: 100%; margin-top: 20px; border-radius: 10px;" data-bs-toggle="tooltip"></a>
<?php endif; $index++; endforeach; ?>
</div>
<div>
<?php $index = 1; foreach ($data["images"] as $image): if ($index % 3 === 0): ?>
<?php $index = 1; foreach ($images as $image): if ($index % 3 === 0): ?>
<a href="#" onclick="showGalleryItem(<?= $index ?>);"><img id="gallery-item-<?= $index ?>" title="<?= l("lang_gallery_uploader") . " " . resolveUser($image["author"]) . " " . timeAgo($image["date"]) ?>" src="/uploads/<?= $image["id"] ?>.webp" style="width: 100%; margin-top: 20px; border-radius: 10px;" data-bs-toggle="tooltip"></a>
<?php endif; $index++; endforeach; ?>
</div>

@ -0,0 +1,48 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
global $_PROFILE; global $_USER;
$id = $_GET['id'] ?? null;
header("Content-Type: text/plain");
if (isset($_POST["list"]) && is_array($_POST["list"])) {
foreach ($_POST["list"] as $uuid) {
if (trim($uuid) === "" || str_contains($uuid, "/") || !file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $uuid . ".webp")) continue;
$requestID = uuid();
file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/requests/" . $requestID . ".json", pf_utf8_encode(json_encode([
"type" => "galleryupload",
"author" => $_USER,
"id" => $id,
"uuid" => $uuid,
"contents" => null,
"summary" => $_POST["summary"],
"date" => date('c')
])));
$_PROFILE["requests"][$id . ":" . $uuid] = $requestID;
}
}
$config = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/email.json"), true);
file_get_contents('https://notifications.equestria.dev/delta', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
"Title: " . formatPonypush("New change request published") . "\r\n" .
"Priority: default\r\n" .
"Tags: requests\r\n" .
"Actions: view, Open change requests, https://delta.equestria.dev/admin/requests/, clear=true\r\n" .
"Authorization: Basic " . base64_encode($config["ntfyuser"] . ":" . $config["ntfypass"]),
'content' => formatPonypush($_PROFILE['first_name'] . " " . $_PROFILE["last_name"] . " published a request to upload an image to " . getNameFromId($id) . (isset($_POST["summary"]) && trim($_POST["summary"]) !== "" ? ": " . $_POST["summary"] : ""))
]
]));
saveProfile();
header("Location: /upload/$id&success");
die();

@ -0,0 +1,67 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
if (isset($_GET["p"])) {
$after = $_GET["p"];
} else {
$after = null;
}
$perPage = 3;
$out = [];
$ids = [];
$list = array_reverse(json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/embeds.json")), true));
$index = 0;
$show = !isset($after);
foreach (array_filter($list, function ($i) {
global $ids;
if (is_string($i)) {
if (in_array($i, $ids)) {
return false;
} else {
$ids[] = $i;
return true;
}
} else {
if (in_array($i["id"], $ids)) {
return false;
} else {
$ids[] = $i["id"];
return true;
}
}
}) as $item) {
if (is_string($item)) {
$item = [
"id" => $item,
"author" => null
];
}
if (isset($after) && !$show) {
if ($item["id"] === $after) {
$show = true;
continue;
} else {
continue;
}
}
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".webp") && !file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".jpg")) continue;
if ($index >= $perPage) break;
$out[] = [
"id" => $item["id"],
"author" => isset($item["author"]) ? getNameFromId($item["author"]) : null
];
$index++;
}
header("Content-Type: application/json");
die(json_encode($out, JSON_PRETTY_PRINT));

@ -1,122 +1,7 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $_USER; global $_PROFILE;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
$id = array_values(array_filter(array_keys($_GET), function ($i) {
return str_starts_with($i, "/") && strlen($i) > 1;
}))[0] ?? null;
if (isset($id)) {
$id = substr($id, 1);
if (!preg_match("/[a-zA-Z0-6]/m", $id)) {
header("Location: /");
die();
}
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
header("Location: /");
die();
}
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
$data = json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")), true);
$title_pre = getNameFromId($id);
} else {
header("Location: /");
die();
}
$title = "lang_upload_title";
if (isset($_GET["old"])) {
require_once "./old.php";
} else {
header("Location: /");
die();
}
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/header.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php";
?>
<form method="post" action="/_upload/save/?id=<?= $id ?>" id="main-form" enctype="multipart/form-data">
<div class="container">
<br><br>
<h1>
<?php if ($id !== $_USER): ?>
<span><?= getNameFromId($id) ?></span>
<span style="float: right;"><a href="/gallery/<?= $id ?>" class="btn btn-outline-dark"><?= l("lang_edit_cancel") ?></a></span>
<?php endif; ?>
</span>
</h1>
<?php if (isset($_GET["success"])): ?>
<div class="alert alert-success">
<strong><?= l("lang_upload_success_0") ?></strong><?= l("lang_upload_success_1") ?> <a href="/upload/<?= $id ?>"><?= l("lang_upload_success_2") ?></a>
</div>
<?php else: ?>
<?php if (isset($_GET['error'])): ?>
<div class="alert alert-danger">
<strong><?= l("lang_upload_error") ?></strong><?= l("lang_upload_errors_" . $_GET['error']) ?>
</div>
<?php endif; ?>
<div>
<p><?= l("lang_upload_select") ?></p>
<input type="file" name="file" style="width: 100%;">
<script>
window.onload = () => {
document.getElementsByName("file")[0].value = "";
}
document.getElementsByName("file")[0].onchange = () => {
if (document.getElementsByName("file")[0].files[0] && document.getElementsByName("file")[0].files[0].type.startsWith("image/")) {
document.getElementById("preview").src = URL.createObjectURL(document.getElementsByName("file")[0].files[0]);
document.getElementById("preview").onload = () => URL.revokeObjectURL(document.getElementById("preview").src);
document.getElementById("form-btn").classList.remove("disabled");
} else {
document.getElementById("preview").src = "/icons/defaultpage.svg";
document.getElementById("form-btn").classList.add("disabled");
}
}
</script>
</div>
<p>
<img src="/icons/defaultpage.svg" style="width: 100%; max-width: 300px; margin-top: 20px; border-radius: 10px;" id="preview">
</p>
<a id="form-btn" class="btn btn-primary disabled"><?= l("lang_upload_confirm") ?></a>
<script>
document.getElementById("form-btn").onclick = (event) => {
new bootstrap.Modal(document.getElementById("confirm")).show()
}
</script>
<?php endif; ?>
<br><br>
</div>
<div class="modal fade" id="confirm">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= l("lang_upload_dialog") ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p><?= l("lang_upload_notice") ?></p>
<p>
<?= l("lang_upload_summary") ?><br>
<!--suppress HtmlFormInputWithoutLabel -->
<textarea class="form-control" name="summary"></textarea>
</p>
<p><?= l("lang_upload_followup") ?></p>
<button class="btn btn-primary"><?= l("lang_edit_confirm_button") ?></button>
</div>
</div>
</div>
</div>
</form>
<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/footer.php"; ?>
require_once "./new.php";
}

@ -0,0 +1,379 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $_USER; global $_PROFILE;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
$id = array_values(array_filter(array_keys($_GET), function ($i) {
return str_starts_with($i, "/") && strlen($i) > 1;
}))[0] ?? null;
if (isset($id)) {
$id = substr($id, 1);
if (!preg_match("/[a-zA-Z0-6]/m", $id)) {
header("Location: /");
die();
}
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
header("Location: /");
die();
}
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
$data = json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")), true);
$title_pre = getNameFromId($id);
} else {
header("Location: /");
die();
}
$title = "lang_newgallery_title";
} else {
header("Location: /");
die();
}
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/header.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php"; global $palette;
?>
<form method="post" action="/_upload/arbitrary/?id=<?= $id ?>" id="main-form" enctype="multipart/form-data">
<input type="file" id="file" style="display: none;" accept="image/png,image/jpeg,image/webp,image/gif,image/bmp,image/avif" multiple>
<script>
let currentFileIndex = 0;
window.uploadQueue = [];
window.uploading = false;
setInterval(() => {
if (!uploading && uploadQueue[0]) {
try {
uploading = true;
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_uploading") ?>";
let data = new FormData();
data.append('upload', uploadQueue[0].file);
window.fetch("/embed/", {
method: 'POST',
body: data
}).then((res) => {
res.text().then((_data) => {
let data;
try {
data = JSON.parse(_data);
console.log(data);
} catch (e) {
console.log(_data);
throw e;
}
if (data.error && data.error.message) {
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_error_message") ?> " + data.error.message;
document.getElementById("list-group-item-" + uploadQueue[0].id + "-remove").classList.remove("disabled");
uploading = false; uploadQueue.shift();
} else if (data.error) {
throw new Error();
} else if (data['url'] && data['uuid']) {
document.getElementById("list-group-item-" + uploadQueue[0].id + "-uuid").value = data['uuid'];
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_complete") ?>";
document.getElementById("list-group-item-" + uploadQueue[0].id + "-remove").classList.remove("disabled");
document.getElementById("list-group-item-" + uploadQueue[0].id + "-preview").style.backgroundImage = `url("${data['url']}")`;
uploading = false; uploadQueue.shift();
} else {
throw new Error();
}
}).catch((e) => {
console.error(e);
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_error_generic") ?>";
document.getElementById("list-group-item-" + uploadQueue[0].id + "-remove").classList.remove("disabled");
uploading = false; uploadQueue.shift();
})
}).catch((e) => {
console.error(e);
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_error_generic") ?>";
document.getElementById("list-group-item-" + uploadQueue[0].id + "-remove").classList.remove("disabled");
uploading = false; uploadQueue.shift();
});
} catch (e) {
console.error(e);
document.getElementById("list-group-item-" + uploadQueue[0].id + "-status").innerText = "<?= l("lang_newgallery_error_generic") ?>";
document.getElementById("list-group-item-" + uploadQueue[0].id + "-remove").classList.remove("disabled");
uploading = false; uploadQueue.shift();
}
}
if (document.getElementById("gallery-items").children.length > 0 && !uploading) {
document.getElementById("form-btn").classList.remove("disabled");
} else {
document.getElementById("form-btn").classList.add("disabled");
}
});
function removeFile(id) {
document.getElementById("list-group-item-" + id).outerHTML = "";
}
window.onload = () => {
document.getElementById("file").value = "";
}
document.getElementById("file").onchange = () => {
for (let file of Array.from(document.getElementById("file").files)) {
picker.hide();
let index = currentFileIndex;
console.log(file);
if (file && file.type.startsWith("image/")) {
document.getElementById("gallery-items").insertAdjacentHTML('beforeend', `
<div class="list-group-item" id="list-group-item-${currentFileIndex}" style="display: grid; grid-template-columns: 15% 1fr; grid-gap: 20px;">
<div style="display: flex; align-items: center;">
<div id="list-group-item-${currentFileIndex}-preview" style="width: 100%; aspect-ratio: 16/9; background-color: black; border-radius: 5px; background-position: center; background-size: contain; background-repeat: no-repeat;"></div>
</div>
<div style="display: flex; align-items: center;">
<div>
<input type="hidden" name="list[${currentFileIndex}]" value="" id="list-group-item-${currentFileIndex}-uuid">
<p>
<b>${file.name}</b><br>
<span id="list-group-item-${currentFileIndex}-status"><?= l("lang_newgallery_waiting") ?></span>
</p>
<button class="btn btn-outline-secondary disabled" id="list-group-item-${currentFileIndex}-remove"><?= l("lang_newgallery_remove") ?></button>
</div>
</div>
</div>
`);
document.getElementById("list-group-item-" + currentFileIndex + "-preview").style.backgroundImage = `url("${URL.createObjectURL(file)}")`;
document.getElementById("list-group-item-" + currentFileIndex + "-remove").onclick = (e) => {
e.preventDefault();
removeFile(index);
return false;
}
uploadQueue.push({
file,
id: currentFileIndex
});
document.getElementById("file").value = "";
}
currentFileIndex++;
}
}
function addExisting(id) {
picker.hide();
let index = currentFileIndex;
document.getElementById("gallery-items").insertAdjacentHTML('beforeend', `
<div class="list-group-item" id="list-group-item-${currentFileIndex}" style="display: grid; grid-template-columns: 15% 1fr; grid-gap: 20px;">
<div style="display: flex; align-items: center;">
<div id="list-group-item-${currentFileIndex}-preview" style="width: 100%; aspect-ratio: 16/9; background-color: black; border-radius: 5px; background-position: center; background-size: contain; background-repeat: no-repeat; background-image: url('/uploads/${id}.webp');"></div>
</div>
<div style="display: flex; align-items: center;">
<div>
<input type="hidden" name="list[${currentFileIndex}]" value="" id="list-group-item-${currentFileIndex}-uuid">
<p>
<b>${id}.webp</b><br>
<span id="list-group-item-${currentFileIndex}-status"><?= l("lang_newgallery_complete") ?></span>
</p>
<button class="btn btn-outline-secondary" id="list-group-item-${currentFileIndex}-remove"><?= l("lang_newgallery_remove") ?></button>
</div>
</div>
</div>
`);
document.getElementById("list-group-item-" + currentFileIndex + "-remove").onclick = (e) => {
e.preventDefault();
removeFile(index);
return false;
}
currentFileIndex++;
}
</script>
<div class="container">
<br><br>
<h1>
<?php if ($id !== $_USER): ?>
<span><?= getNameFromId($id) ?></span>
<span style="float: right;"><a href="/gallery/<?= $id ?>" class="btn btn-outline-dark"><?= l("lang_edit_cancel") ?></a></span>
<?php endif; ?>
</span>
</h1>
<?php if (isset($_GET['error'])): ?>
<div class="alert alert-danger">
<strong><?= l("lang_upload_error") ?></strong><?= l("lang_upload_errors_" . $_GET['error']) ?>
</div>
<?php endif; ?>
<?php if (isset($_GET["success"])): ?>
<div class="alert alert-success">
<strong><?= l("lang_newgallery_success_0") ?></strong><?= l("lang_newgallery_success_1") ?>
</div>
<?php endif; ?>
<div>
<p><?= l("lang_newgallery_intro") ?></p>
<div class="btn-group">
<a id="upload-btn" onclick="resetPicker(); picker.show();" class="btn btn-primary"><?= l("lang_newgallery_add") ?></a>
<a id="form-btn" class="btn btn-outline-primary disabled"><?= l("lang_newgallery_upload") ?></a>
</div>
</div>
<div class="list-group" id="gallery-items" style="margin-top: 20px;"></div>
<script>
document.getElementById("form-btn").onclick = (event) => {
new bootstrap.Modal(document.getElementById("confirm")).show()
}
</script>
<br><br>
</div>
<div class="modal fade" id="confirm">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= l("lang_upload_dialog") ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p><?= l("lang_upload_notice") ?></p>
<p>
<?= l("lang_upload_summary") ?><br>
<!--suppress HtmlFormInputWithoutLabel -->
<textarea class="form-control" name="summary"></textarea>
</p>
<p><?= l("lang_upload_followup") ?></p>
<button class="btn btn-primary"><?= l("lang_edit_confirm_button") ?></button>
</div>
</div>
</div>
</div>
</form>
<div class="modal modal-xl fade" id="picker">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= l("lang_newgallery_picker_title") ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<a class="card picker-card picker-drop" onclick="document.getElementById('file').click();" style="margin-bottom: 20px;">
<div class="card-body">
<img style="width: 32px;" alt="" src="/icons/upload.svg">
<span style="vertical-align: middle;"><?= l("lang_newgallery_picker_upload") ?></span>
</div>
</a>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;" id="existing-list"></div>
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 10px; margin-top: 20px;" id="existing-loader">
<svg class="spinner" width="32px" height="32px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
</svg>
</div>
</div>
<script>
let lastPageItem = null;
let doneLoading = false;
let loading = false;
window.shouldLoad = false;
function resetPicker() {
lastPageItem = null;
document.getElementById("existing-loader").style.display = "flex";
document.getElementById("existing-list").innerHTML = "";
}
let options = {
root: document.getElementById("picker"),
rootMargin: "0px",
threshold: 1.0,
};
let observer = new IntersectionObserver((entries) => {
shouldLoad = entries[0].isIntersecting;
}, options);
observer.observe(document.getElementById("existing-loader"));
setInterval(() => {
if (shouldLoad && !loading && !doneLoading) {
loading = true;
fetch("/_upload/existing/" + (lastPageItem ? "?p=" + lastPageItem : "")).then((res) => {
res.text().then((_data) => {
let data = JSON.parse(_data);
console.log(data);
if (data.length < 3) {
doneLoading = true;
document.getElementById("existing-loader").style.display = "none";
}
if (data.length > 0) {
lastPageItem = data[data.length - 1].id;
}
for (let item of data) {
document.getElementById("existing-list").insertAdjacentHTML('beforeend', `
<a class="card picker-card" onclick="addExisting('${item.id}');">
<div class="card-body">
<div style="background-image: url('/uploads/${item.id}.webp'); background-color: black;aspect-ratio: 16/9;width: calc(100% + 2rem);margin-left: -1rem;background-size: contain;background-position: center;background-repeat: no-repeat;margin-right: -1rem;border-radius: 0.375rem;margin-top: -1rem;"></div>
${item.author ? `<span style="margin-top: 1rem;display: block; text-align: center;"><?= l("lang_newgallery_picker_uploader") ?>${item.author}</span>` : `<span style="margin-top: 1rem;display: block; text-align: center;"><?= l("lang_newgallery_picker_unknown") ?></span>`}
</div>
</a>
`);
}
loading = false;
})
})
}
});
</script>
</div>
</div>
</div>
<script>
let picker = new bootstrap.Modal(document.getElementById("picker"));
</script>
<style>
.picker-card {
background-color: var(--palette-3);
border-color: var(--palette-5);
border-width: 2px;
color: inherit !important;
cursor: pointer;
text-decoration: inherit !important;
}
.picker-card:hover {
opacity: .75;
}
.picker-card:active {
opacity: .5;
}
.picker-drop {
border-style: dashed;
text-align: center;
}
</style>
<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/footer.php"; ?>

@ -0,0 +1,122 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $_USER; global $_PROFILE;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
$id = array_values(array_filter(array_keys($_GET), function ($i) {
return str_starts_with($i, "/") && strlen($i) > 1;
}))[0] ?? null;
if (isset($id)) {
$id = substr($id, 1);
if (!preg_match("/[a-zA-Z0-6]/m", $id)) {
header("Location: /");
die();
}
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
header("Location: /");
die();
}
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")) {
$data = json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $id . ".json")), true);
$title_pre = getNameFromId($id);
} else {
header("Location: /");
die();
}
$title = "lang_upload_title";
} else {
header("Location: /");
die();
}
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/header.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php";
?>
<form method="post" action="/_upload/save/?id=<?= $id ?>" id="main-form" enctype="multipart/form-data">
<div class="container">
<br><br>
<h1>
<?php if ($id !== $_USER): ?>
<span><?= getNameFromId($id) ?></span>
<span style="float: right;"><a href="/gallery/<?= $id ?>" class="btn btn-outline-dark"><?= l("lang_edit_cancel") ?></a></span>
<?php endif; ?>
</span>
</h1>
<?php if (isset($_GET["success"])): ?>
<div class="alert alert-success">
<strong><?= l("lang_upload_success_0") ?></strong><?= l("lang_upload_success_1") ?> <a href="/upload/<?= $id ?>"><?= l("lang_upload_success_2") ?></a>
</div>
<?php else: ?>
<?php if (isset($_GET['error'])): ?>
<div class="alert alert-danger">
<strong><?= l("lang_upload_error") ?></strong><?= l("lang_upload_errors_" . $_GET['error']) ?>
</div>
<?php endif; ?>
<div>
<p><?= l("lang_upload_select") ?></p>
<input type="file" name="file" style="width: 100%;">
<script>
window.onload = () => {
document.getElementsByName("file")[0].value = "";
}
document.getElementsByName("file")[0].onchange = () => {
if (document.getElementsByName("file")[0].files[0] && document.getElementsByName("file")[0].files[0].type.startsWith("image/")) {
document.getElementById("preview").src = URL.createObjectURL(document.getElementsByName("file")[0].files[0]);
document.getElementById("preview").onload = () => URL.revokeObjectURL(document.getElementById("preview").src);
document.getElementById("form-btn").classList.remove("disabled");
} else {
document.getElementById("preview").src = "/icons/defaultpage.svg";
document.getElementById("form-btn").classList.add("disabled");
}
}
</script>
</div>
<p>
<img src="/icons/defaultpage.svg" style="width: 100%; max-width: 300px; margin-top: 20px; border-radius: 10px;" id="preview">
</p>
<a id="form-btn" class="btn btn-primary disabled"><?= l("lang_upload_confirm") ?></a>
<script>
document.getElementById("form-btn").onclick = (event) => {
new bootstrap.Modal(document.getElementById("confirm")).show()
}
</script>
<?php endif; ?>
<br><br>
</div>
<div class="modal fade" id="confirm">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= l("lang_upload_dialog") ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p><?= l("lang_upload_notice") ?></p>
<p>
<?= l("lang_upload_summary") ?><br>
<!--suppress HtmlFormInputWithoutLabel -->
<textarea class="form-control" name="summary"></textarea>
</p>
<p><?= l("lang_upload_followup") ?></p>
<button class="btn btn-primary"><?= l("lang_edit_confirm_button") ?></button>
</div>
</div>
</div>
</div>
</form>
<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/footer.php"; ?>

@ -76,6 +76,7 @@ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/requests/" . $uuid
"type" => "galleryupload",
"author" => $_USER,
"id" => $id,
"uuid" => $uuid,
"contents" => null,
"summary" => $_POST["summary"],
"date" => date('c')

@ -50,7 +50,7 @@ if ($request["type"] === "galleryupload" && !isset($_GET['mark'])) {
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $request["id"] . ".json")) {
$gallery = json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gallery/" . $request["id"] . ".json")), true);
$gallery["images"][] = [
"id" => $id,
"id" => $request["uuid"],
"author" => $request["author"],
"date" => $request["date"]
];

@ -6,6 +6,19 @@ $title_pre = l("lang_admin_titles_handoff");
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/header.php";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php";
$indexes = [
"Primary",
"On Primary",
"On Background",
"On Primary Container",
"Secondary 35/Secondary 80",
"Secondary 30/Secondary 90",
"Secondary 25/Secondary 95",
"Surface Variant",
"Neutral 10/Neutral 95",
"Background"
];
?>
<div class="container">
@ -15,6 +28,12 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php";
<code><?= $_COOKIE["DeltaHandoffPalette"] ?? "-" ?></code>
<ul>
<?php global $palette; foreach ($palette as $index => $color): ?>
<li>[<?= $index ?>, <?= $indexes[9 - $index] ?? "(unknown)" ?>] <code>#<?= $color ?></code> <div style="background-color: #<?= $color ?>; width: 16px; height: 16px; display: inline-block;"></div></li>
<?php endforeach; ?>
</ul>
<br><br>
</div>

@ -83,7 +83,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/navigation.php";
</details>
<?php if ($request["type"] === "galleryupload"): ?>
<p><img src="/uploads/<?= $request["_id"] ?>.webp" style="max-width: 30vw; max-height: 30vh;"></p>
<p><img src="/uploads/<?= $request["uuid"] ?? $request["_id"] ?>.webp" style="max-width: 30vw; max-height: 30vh;"></p>
<?php elseif(isset($request["contents"]) && trim($request["contents"]) !== ""): ?>
<div style="max-height: 300px; overflow: auto; background-color: rgba(0, 0, 0, .25); padding: 5px 10px; border-radius: 10px; margin-bottom: 20px;">
<?= $request["contents"] ?>

@ -6,6 +6,8 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
global $_PROFILE; global $_USER;
$uuid = uuid();
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
header("Content-Type: application/json");
@ -61,7 +63,12 @@ switch ($_FILES["upload"]["type"]) {
break;
}
imagewebp($im, $_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
$res = false;
while (!$res) {
$res = imagewebp($im, $_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
}
$size = getimagesize($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
$ratio_orig = $size[0] / $size[1];
@ -76,11 +83,32 @@ if ($width / $height > $ratio_orig) {
if ($size[0] > 1080 || $size[1] > 1080) {
imagescale($im, $width, $height);
imagewebp($im, $_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
$res = false;
while (!$res) {
$res = imagewebp($im, $_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
}
}
$list = json_decode(pf_utf8_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/embeds.json")), true);
foreach ($list as $item) {
if (is_string($item)) {
$list = array_map(function ($i) {
if (is_string($i)) {
return [
"id" => $i,
"author" => null
];
} else {
return $i;
}
}, $list);
break;
}
}
foreach ($list as $item) {
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".webp") && file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp") === file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".webp")) {
$uuid = $item["id"];
@ -88,19 +116,22 @@ foreach ($list as $item) {
} elseif (file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/archive/" . $item["id"] . ".webp") && file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp") === file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/uploads/archive/" . $item["id"] . ".webp")) {
$uuid = $item["id"];
unlink($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
rename($_SERVER['DOCUMENT_ROOT'] . "/uploads/archive/" . $item["id"] . ".webp", $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".web");
rename($_SERVER['DOCUMENT_ROOT'] . "/uploads/archive/" . $item["id"] . ".webp", $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $item["id"] . ".webp");
} else {
rename($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp", $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $uuid . ".web");
rename($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp", $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $uuid . ".webp");
$list[] = [
"id" => $uuid,
"author" => $_USER
];
break;
}
}
file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/embeds.json", pf_utf8_encode(json_encode($list)));
die(json_encode([
"url" => "/uploads/" . $uuid . ".webp"
"url" => "/uploads/" . $uuid . ".webp",
"uuid" => $uuid
]));

@ -282,8 +282,9 @@ foreach (array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/uploads/"), function
}
}
println(" " . $upload . ", will delete: " . (!$used && time() - filemtime($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $upload) > 3600 ? "yes" : "no") . ", difference: " . (time() - filemtime($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $upload)) . ", used: " . ($used ? "yes" : "no"));
if (!$used && time() - filemtime($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $upload) > 3600) {
println(" " . $upload);
rename($_SERVER['DOCUMENT_ROOT'] . "/uploads/" . $upload, $_SERVER['DOCUMENT_ROOT'] . "/uploads/archive/" . $upload);
}
}

@ -1113,5 +1113,31 @@
"description": "You are now ready to use Delta. You can use the integrated support feature if you need it. Click on Done to access Delta."
}
]
},
"newgallery": {
"title": "Add images",
"intro": "Select the files you want to publish in this album.",
"upload": "Publish images",
"add": "Add another image",
"waiting": "Waiting for upload...",
"uploading": "Uploading to server...",
"remove": "Remove image",
"error": {
"message": "Upload failed due to the following error:",
"generic": "Upload failed"
},
"complete": "Upload completed",
"success": [
"Success: ",
"The images you have uploaded have been successfully submitted for review to the administrators."
],
"picker": {
"title": "Select an image",
"upload": "Upload from your device",
"uploader": "Published by ",
"unknown": "Unknown publisher"
},
"notice": "Do you want to publish these images to be reviewed by the administrators? Make sure these are the right images before you send them, as you cannot change them afterwards.",
"summary": "Optionally describe these images and why they should be added to the album:"
}
}

@ -1109,5 +1109,31 @@
"description": "Vous êtes désormais prêt·e à utiliser Delta. Vous pouvez utiliser l'option d'aide intégrée si besoin. Cliquez sur Terminer pour accéder à Delta."
}
]
},
"newgallery": {
"title": "Ajouter des images",
"intro": "Sélectionnez les fichiers que vous voulez publier dans cet album.",
"upload": "Publier les images",
"add": "Ajouter une autre",
"waiting": "En attente d'envoi...",
"uploading": "Envoi au serveur...",
"remove": "Supprimer l'image",
"error": {
"message": "Échec de l'envoi en raison de l'erreur suivante :",
"generic": "Échec de l'envoi"
},
"complete": "Envoi terminé",
"success": [
"Terminé : ",
"Les images que vous avez envoyées ont été soumises pour relecture par les administrateur·ice·s."
],
"picker": {
"title": "Sélectionner une image",
"upload": "Importer depuis votre appareil",
"uploader": "Publié par ",
"unknown": "Auteur inconnu"
},
"notice": "Voulez-vous publier ces images pour être revues par les administrateur·ice·s ? Assurez-vous qu'il s'agit des bonnes images avant de les envoyer, étant donné que vous ne pouvez pas les modifier après.",
"summary": "En option, décrivez ces images et pourquoi elles doivent être ajoutées à cet album :"
}
}
Loading…
Cancel
Save