diff options
author | Minteck <contact@minteck.org> | 2022-10-10 20:51:39 +0200 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2022-10-10 20:51:39 +0200 |
commit | 108525534c28013cfe1897c30e4565f9893f3766 (patch) | |
tree | dd3e5132971f96ab5f05e7f3f8f6dbbf379a19bd /pages/docs.php | |
parent | 2162eaa06f7e4764eb3dcfe130ec2c711d0c62ab (diff) | |
download | pluralconnect-108525534c28013cfe1897c30e4565f9893f3766.tar.gz pluralconnect-108525534c28013cfe1897c30e4565f9893f3766.tar.bz2 pluralconnect-108525534c28013cfe1897c30e4565f9893f3766.zip |
Update
Diffstat (limited to 'pages/docs.php')
-rw-r--r-- | pages/docs.php | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/pages/docs.php b/pages/docs.php deleted file mode 100644 index bbc3054..0000000 --- a/pages/docs.php +++ /dev/null @@ -1,361 +0,0 @@ -<?php - -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.php"; global $title; global $isLoggedIn; global $_PROFILE; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/random.php"; - -$parts = explode("/", $_GET['_']); -$select = $parts[2] ?? null; - -if ($select === "add") { - $id = random(); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $id . ".json", json_encode([ - "name" => "Untitled document ($id)", - "category" => null, - "contents" => "<div class='alert alert-primary'>This is a new document you just created.</div>", - "last" => [ - "author" => $_PROFILE["login"], - "date" => time() - ] - ])); - - header("Location: /-/docs/$id"); - die(); -} elseif (isset($select)) { - if (ctype_alnum($select) && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json")) { - $id = $select; - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json"), true); - $titleBase = " · " . $title . " · Cold Haze"; - $title = $data["name"] . " · " . $title; - } else { - header("Location: /-/docs"); - die(); - } -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; - -?> - -<br> -<div class="container"> - <div> - <?php if (isset($data)): ?><div id="page-content"> - <h2> - <span contenteditable="true" id="document-name" style="outline: none;"><?= $data["name"] ?></span> - <a href="/-/docs" class="small btn btn-outline-light" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; color:white;">Back</a> - </h2> - <p><b>Category:</b> <span id="category" contenteditable="true" style="outline: none;"><?= $data["category"] ?? "Unsorted" ?></span></p> - <p> - <?php if ($data["last"]["date"] === 0): ?> - Last modified <span id="last-edit-time" class="relative-time" data-relative-timestamp="">never</span> - <?php else: ?> - Last modified <span id="last-edit-time" class="relative-time" data-relative-timestamp="<?= $data["last"]["date"] ?>"><?= timeAgo($data["last"]["date"]) ?></span> - <?php if ($data["last"]["author"] !== $_PROFILE["login"]): ?> - <span id="last-edit-author">by <?= $data["last"]["author"] === "raindrops" ? "the Raindrops System" : "the Cloudburst System" ?></span> - <?php endif; ?> - <?php endif; ?> - · <span id="editor-save-status" class="text-muted">Saved</span> - </p> - - <textarea id="editor"><?= $data["contents"] ?></textarea> - - <script src="/assets/editor/editor.js"></script> - <script> - let editor; - ClassicEditor - .create( document.querySelector( '#editor' ), { - toolbar: [ - 'undo', 'redo', '|', 'removeFormat', '|', 'heading', '|', 'fontSize', 'fontColor', 'fontBackgroundColor', 'alignment', '|', 'bold', 'italic', 'underline', 'strikethrough', '|', 'subscript', 'superscript', '|', 'code', '|', 'outdent', 'indent', '|', 'bulletedList', 'numberedList', '|', 'link', 'imageUpload', 'mediaEmbed', 'blockQuote', 'insertTable', 'codeBlock', '|', 'horizontalLine' - ] - } ) - - .then( newEditor => { - editor = newEditor; - } ) - .catch( error => { - console.error( error ); - } ); - </script> - <!--suppress CssUnresolvedCustomProperty --> - <style> - :root { - --ck-color-base-background: transparent; - } - - .ck-toolbar { - filter: invert(1); - border-bottom-left-radius: var(--ck-border-radius) !important; - border-bottom-right-radius: var(--ck-border-radius) !important; - border-bottom-width: 1px !important; - } - - .ck-tooltip__text { - color: white !important; - } - - .ck-dropdown__panel { - background: #ddd !important; - } - - .ck-color-grid__tile { - filter: invert(1); - } - - .ck-balloon-rotator { - background-color: #ccc !important; - } - - .ck-balloon-panel { - filter: invert(1); - } - - .ck-editor__editable { - border-color: transparent !important; - } - </style> - <script> - - let titleBase = "<?= $titleBase ?>"; - let lastSavedData = editor.getData(); - let lastFetchedData = editor.getData(); - let timeSinceLastModified = 0; - let saving = false; - - async function save() { - let data = editor.getData(); - document.getElementById("editor-save-status").innerHTML = "Saving..."; - document.getElementById("editor-save-status").classList.remove("text-danger"); - document.getElementById("editor-save-status").classList.remove("text-muted"); - document.getElementById("editor-save-status").classList.remove("text-warning"); - document.getElementById("editor-save-status").classList.add("text-primary"); - saving = true; - - try { - await window.fetch("/api/docs?id=<?= $id ?>", { - method: "POST", - body: JSON.stringify({ content: data, name: document.getElementById("document-name").innerText, category: document.getElementById("category").innerText }) - }); - document.getElementById("last-edit-time").setAttribute("data-relative-timestamp", (new Date().getTime() / 1000).toFixed(0)); - if (document.getElementById("last-edit-author")) document.getElementById("last-edit-author").outerHTML = ""; - document.title = document.getElementById("document-name").innerText + titleBase; - document.getElementById("editor-save-status").innerHTML = "Saved"; - document.getElementById("editor-save-status").classList.remove("text-danger"); - document.getElementById("editor-save-status").classList.add("text-muted"); - document.getElementById("editor-save-status").classList.remove("text-warning"); - document.getElementById("editor-save-status").classList.remove("text-primary"); - lastSavedData = data; - saving = false; - } catch (e) { - console.error(e); - document.getElementById("editor-save-status").innerHTML = "Failed to save"; - document.getElementById("editor-save-status").classList.add("text-danger"); - document.getElementById("editor-save-status").classList.remove("text-muted"); - document.getElementById("editor-save-status").classList.remove("text-warning"); - document.getElementById("editor-save-status").classList.remove("text-primary"); - } - } - - document.onclick = async () => { - if (saving) return; - - if (editor.getData() !== lastSavedData) { - await save(); - } - } - - setInterval(async () => { - if (saving) return; - - if (editor.getData() !== lastSavedData) { - document.getElementById("editor-save-status").innerHTML = "Modified"; - document.getElementById("editor-save-status").classList.remove("text-danger"); - document.getElementById("editor-save-status").classList.remove("text-muted"); - document.getElementById("editor-save-status").classList.add("text-warning"); - document.getElementById("editor-save-status").classList.remove("text-primary"); - - if (editor.getData() !== lastFetchedData) { - lastFetchedData = editor.getData(); - timeSinceLastModified = 0; - } else { - timeSinceLastModified++; - } - - if (timeSinceLastModified > 20 || !document.hasFocus()) { - await save(); - } - } else { - timeSinceLastModified = 0; - } - }, 100) - - </script> - </div><?php else: ?> - <h2>Documents</h2> - <div id="list"> - <?php - - $documents = array_map(function ($i) { - return [ - "id" => substr($i, 0, -5), - ...(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $i), true) ?? []) - ]; - }, array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs"), function ($i) { - return !str_starts_with($i, ".") && str_ends_with($i, ".json"); - })); - - $deletable = array_values(array_filter($documents, function ($i) { - return strip_tags($i["contents"]) === "/delete"; - })); - $unsorted_pre = array_values(array_filter($documents, function ($i) { - return strip_tags($i["contents"]) !== "/delete"; - })); - - $unsorted = []; - $categories = []; - foreach ($unsorted_pre as $item) { - if (isset($item["category"])) { - $existing_categories = array_keys($categories); - $matched_category = null; - - foreach ($existing_categories as $existing_category) { - if (levenshtein($item["category"], $existing_category) < 3) { - $matched_category = $existing_category; - } - } - - $selected_category = $matched_category ?? $item["category"]; - if (!isset($categories[$selected_category])) $categories[$selected_category] = []; - $categories[$selected_category][] = $item; - } else { - $unsorted[] = $item; - } - } - - uasort($unsorted, function ($a, $b) { - return $b["last"]["date"] - $a["last"]["date"]; - }); - - uasort($deletable, function ($a, $b) { - return $b["last"]["date"] - $a["last"]["date"]; - }); - - ?> - - <?php foreach ($categories as $category => $items): ?> - <h4><?= $category ?></h4><div class="list-group"> - <?php foreach ($items as $item): ?> - <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (strip_tags($item["contents"]) === "/delete"): ?>opacity-75<?php endif; ?>"> - <?= $item["name"] ?> - <?php if (strip_tags($item["contents"]) === "/delete"): ?> - <span class="badge bg-warning rounded-pill text-black">Deleting in <?= round((($item["last"]["date"] + 86400) - time()) / 3600) ?> hours</span> - <?php else: ?> - <span class="relative-time text-muted" data-relative-timestamp="<?= $item["last"]["date"] ?>"><?= timeAgo($item["last"]["date"]) ?></span> - <?php endif; ?> - </a> - <?php endforeach; ?></div> - <hr> - <?php endforeach; ?> - - <h4>Unsorted</h4><div class="list-group"> - <?php foreach ($unsorted as $item): ?> - <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (strip_tags($item["contents"]) === "/delete"): ?>opacity-75<?php endif; ?>"> - <?= $item["name"] ?> - <?php if (strip_tags($item["contents"]) === "/delete"): ?> - <span class="badge bg-warning rounded-pill text-black">Deleting in <?= round((($item["last"]["date"] + 86400) - time()) / 3600) ?> hours</span> - <?php else: ?> - <span class="relative-time text-muted" data-relative-timestamp="<?= $item["last"]["date"] ?>"><?= timeAgo($item["last"]["date"]) ?></span> - <?php endif; ?> - </a> - <?php endforeach; ?></div> - - <hr> - <h4>Marked for deletion</h4><div class="list-group"> - <?php foreach ($deletable as $item): ?> - <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (strip_tags($item["contents"]) === "/delete"): ?>opacity-75<?php endif; ?>"> - <?= $item["name"] ?> - <?php if (strip_tags($item["contents"]) === "/delete"): ?> - <span class="badge bg-warning rounded-pill text-black">Deleting in <?= round((($item["last"]["date"] + 86400) - time()) / 3600) ?> hours</span> - <?php else: ?> - <span class="relative-time text-muted" data-relative-timestamp="<?= $item["last"]["date"] ?>"><?= timeAgo($item["last"]["date"]) ?></span> - <?php endif; ?> - </a> - <?php endforeach; ?></div> - </div> - - <hr> - <div id="page-content"> - <a href="/-/docs/add">Create a new document</a> - </div> - <?php endif; ?> - </div> -</div> - -<script> - setInterval(async () => { - Array.from(document.getElementsByClassName("relative-time")).forEach((el) => { - el.innerText = timeAgo(parseInt(el.getAttribute("data-relative-timestamp")) * 1000); - }) - }, 1000) - - function timeAgo(time) { - if (!isNaN(parseInt(time))) { - time = new Date(time).getTime(); - } - - let periods = ["sec.", "mn.", "hr.", "d.", "wk.", "mo.", "y.", "ages"]; - - let lengths = ["60", "60", "24", "7", "4.35", "12", "100"]; - - let now = new Date().getTime(); - - let difference = Math.round((now - time) / 1000); - let tense; - let period; - - if (difference <= 10 && difference >= 0) { - return "now"; - } else if (difference > 0) { - tense = "ago"; - } else { - tense = "later"; - } - - let j; - - for (j = 0; difference >= lengths[j] && j < lengths.length - 1; j++) { - difference /= lengths[j]; - } - - difference = Math.round(difference); - - period = periods[j]; - - return `${difference} ${period} ${tense}`; - } -</script> -<style> - .list-group-item { - color: #fff; - background-color: #222; - border: 1px solid rgba(255, 255, 255, .125); - } - - .list-group-item.disabled { - color: #fff; - background-color: #222; - border-color: rgba(255, 255, 255, .125); - opacity: .75; - } - - .list-group-item:hover { - background-color: #252525; - color: #ddd; - } - - .list-group-item:active, .list-group-item:focus { - background-color: #272727; - color: #bbb; - } -</style> - -<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php'; ?> |