summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaindropsSys <contact@minteck.org>2023-05-22 15:54:02 +0200
committerRaindropsSys <contact@minteck.org>2023-05-22 15:54:02 +0200
commitaf1fb5ecf169c1d2c9b565063e7383617c760455 (patch)
tree853197089451c6757adb578979cc99d4201a902a
parent7348d637ca1b4b5ad6bf840adb409eed7cc8d9ec (diff)
downloaddelta-af1fb5ecf169c1d2c9b565063e7383617c760455.tar.gz
delta-af1fb5ecf169c1d2c9b565063e7383617c760455.tar.bz2
delta-af1fb5ecf169c1d2c9b565063e7383617c760455.zip
Updated 10 files and added 4 files (automated)
-rw-r--r--_gallery/index.php13
-rw-r--r--_upload/arbitrary/index.php48
-rw-r--r--_upload/existing/index.php67
-rw-r--r--_upload/index.php123
-rw-r--r--_upload/new.php379
-rw-r--r--_upload/old.php122
-rw-r--r--_upload/save/index.php1
-rw-r--r--admin/approve/index.php2
-rw-r--r--admin/handoff/index.php19
-rw-r--r--admin/requests/index.php2
-rw-r--r--embed/index.php41
-rw-r--r--includes/jobs-handler.php3
-rw-r--r--lang/en.json26
-rw-r--r--lang/fr.json26
14 files changed, 741 insertions, 131 deletions
diff --git a/_gallery/index.php b/_gallery/index.php
index 102711e..450928d 100644
--- a/_gallery/index.php
+++ b/_gallery/index.php
@@ -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>
diff --git a/_upload/arbitrary/index.php b/_upload/arbitrary/index.php
new file mode 100644
index 0000000..2271780
--- /dev/null
+++ b/_upload/arbitrary/index.php
@@ -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(); \ No newline at end of file
diff --git a/_upload/existing/index.php b/_upload/existing/index.php
new file mode 100644
index 0000000..decdffb
--- /dev/null
+++ b/_upload/existing/index.php
@@ -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)); \ No newline at end of file
diff --git a/_upload/index.php b/_upload/index.php
index 1e42f1d..2b90a80 100644
--- a/_upload/index.php
+++ b/_upload/index.php
@@ -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"; ?> \ No newline at end of file
+ require_once "./new.php";
+} \ No newline at end of file
diff --git a/_upload/new.php b/_upload/new.php
new file mode 100644
index 0000000..98241e7
--- /dev/null
+++ b/_upload/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"; ?> \ No newline at end of file
diff --git a/_upload/old.php b/_upload/old.php
new file mode 100644
index 0000000..1e42f1d
--- /dev/null
+++ b/_upload/old.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"; ?> \ No newline at end of file
diff --git a/_upload/save/index.php b/_upload/save/index.php
index bfc466e..2272e5e 100644
--- a/_upload/save/index.php
+++ b/_upload/save/index.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')
diff --git a/admin/approve/index.php b/admin/approve/index.php
index fdca968..b288e18 100644
--- a/admin/approve/index.php
+++ b/admin/approve/index.php
@@ -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"]
];
diff --git a/admin/handoff/index.php b/admin/handoff/index.php
index 804ecd3..86fb763 100644
--- a/admin/handoff/index.php
+++ b/admin/handoff/index.php
@@ -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>
diff --git a/admin/requests/index.php b/admin/requests/index.php
index fe7491e..5e136f0 100644
--- a/admin/requests/index.php
+++ b/admin/requests/index.php
@@ -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"] ?>
diff --git a/embed/index.php b/embed/index.php
index feeb6ba..4fe3989 100644
--- a/embed/index.php
+++ b/embed/index.php
@@ -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,31 +83,55 @@ 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"];
unlink($_SERVER['DOCUMENT_ROOT'] . "/uploads/temp-" . $uuid . ".webp");
} 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
])); \ No newline at end of file
diff --git a/includes/jobs-handler.php b/includes/jobs-handler.php
index 79bca78..5639091 100644
--- a/includes/jobs-handler.php
+++ b/includes/jobs-handler.php
@@ -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);
}
}
diff --git a/lang/en.json b/lang/en.json
index 91235bd..478f141 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -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:"
}
} \ No newline at end of file
diff --git a/lang/fr.json b/lang/fr.json
index 636b09f..9e5e0df 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -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 :"
}
} \ No newline at end of file