summaryrefslogtreecommitdiff
path: root/static/js/editor.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/js/editor.js')
-rw-r--r--static/js/editor.js805
1 files changed, 805 insertions, 0 deletions
diff --git a/static/js/editor.js b/static/js/editor.js
new file mode 100644
index 0000000..7804f4c
--- /dev/null
+++ b/static/js/editor.js
@@ -0,0 +1,805 @@
+// uses functions in utils.js
+var host = window.location.protocol + "//" + window.location.host;
+var collection_id;
+var latest_timestamp = -1;
+
+// "global" map variables
+var map;
+var location_picking = false;
+
+// layer variables
+const media_markers_l = L.layerGroup([]); // media markers
+const media_markers_ref = {};
+const text_markers = L.layerGroup([]); // polyline routes
+
+// collection info in JSON
+const collection_media = {};
+const collection_notes = {};
+const collection_perms = {};
+const collection_info = {};
+const media_divs = {};
+const changes = { "name" : false, "info" : false, "timestamp" : false }
+
+//
+var mode = 0; // 0 = media, 1 = notes, 2 = routes. the index of hte currently selected tab
+var ascending = true;
+const selected_media_ids = [];
+var is_picking_location = false;
+var last_selected_index = -1;
+var media_modal_open = false;
+var share_modal_open = false;
+var collection_modal_open = false;
+
+var Media_Icon = L.Icon.extend({
+ options: {
+ shadowUrl: 'static/img/marker_background.png',
+ iconSize: [60, 45],
+ shadowSize: [72, 62],
+ iconAnchor: [30, 55],
+ shadowAnchor: [36, 62],
+ popupAnchor: [-3, -76]
+ }
+});
+
+// RUN ON PAGE LOAD
+window.onload = function() {
+ document.getElementById("share-modal").addEventListener("click", close_share_modal);
+ document.getElementById("share-box").addEventListener("click", stop_propagation);
+ document.getElementById("collection-modal").addEventListener("click", close_collection_modal);
+ document.getElementById("collection-box").addEventListener("click", stop_propagation);
+
+ collection_id = document.getElementById("collection_id").innerText;
+ map = L.map('map').setView([13.6760758587756, -89.21535464697462], 10);
+ L.tileLayer('https://tiles.stadiamaps.com/tiles/outdoors/{z}/{x}/{y}{r}.{ext}?api_key=24746ff5-179d-482f-97a8-0267c5b276a1', {
+ minZoom: 0,
+ maxZoom: 20,
+ ext: 'png'
+ }).addTo(map);
+
+
+ map.addLayer(media_markers_l);
+ map.addLayer(text_markers);
+ var layerControl = L.control.layers(null,null,{collapsed:false});
+ layerControl.addOverlay(media_markers_l, "Media");
+ layerControl.addOverlay(text_markers, "Notes");
+ layerControl.addTo(map);
+
+ map.on('click', function(e) {
+ var coords = e.latlng;
+ handle_map_click(coords["lat"], coords["lng"]);
+ });
+
+ request_latest_info();
+}
+var intervalId = window.setInterval(function(){ // constantly get latest info from server
+ request_latest_info();
+ }, 5000);
+
+ // keyboard event listener for ESC to clear selection or cancel location picking
+document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') {
+ if(media_modal_open) {
+ close_media_preview();
+ return;
+ }
+ if(share_modal_open) {
+ close_share_modal();
+ return;
+ }
+ if(collection_modal_open) {
+ close_collection_modal();
+ return;
+ }
+ if (is_picking_location) {
+ disable_picking();
+ return;
+ }
+ clear_selection();
+ update_content_editing_box();
+ }
+ if (e.key == 'c') {
+ if( e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA" ) return;
+ if( e.target.isContentEditable ) return;
+ if(selected_media_ids.length)picker_clicked();
+ return;
+ }
+ // select elements by arrow keys
+ if (e.key == 'a' || e.key == 'd') {
+ if( e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA" ) return;
+ if(last_selected_index != -1) {
+ const new_index = last_selected_index + (e.key == 'a' ? -1 : 1);
+ const media = document.querySelector(`.media[data-index="${new_index}"]`);
+ if (media) {
+ clear_selection();
+
+ media.classList.add('selected');
+ selected_media_ids.push(media.dataset.id);
+ last_selected_index = parseInt(media.dataset.index);
+ media.scrollIntoView();
+ //map.panTo(media_markers_ref[media.dataset.id].latlng);
+
+ update_content_editing_box();
+ }
+ }
+ }
+ if (e.key == 'w' || e.key == 's') {
+ if( e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA" ) return;
+ if(last_selected_index != -1) {
+ const grid = document.getElementById("media_grid");
+ const grid_computed_style = window.getComputedStyle(grid);
+ const grid_cols = grid_computed_style.getPropertyValue("grid-template-columns").split(" ").length;
+
+ const new_index = last_selected_index + (e.key == 'w' ? -1 : 1)*grid_cols;
+ const media = document.querySelector(`.media[data-index="${new_index}"]`);
+ console.log(media);
+ if (media) {
+ clear_selection();
+
+ media.classList.add('selected');
+ selected_media_ids.push(media.dataset.id);
+ last_selected_index = parseInt(media.dataset.index);
+ media.scrollIntoView();
+ //map.panTo(media_markers_ref[media.dataset.id].latlng);
+
+ update_content_editing_box();
+ }
+ }
+ }
+});
+
+function stop_propagation(event) {
+ console.log("stop event propagation");
+ event.stopPropagation();
+}
+
+
+function set_tab(evt, tab_id) {
+ if(is_picking_location) return;
+ // Hide all tabs' content and mark all tabs as unselected
+ var tab_content = document.getElementsByClassName("tab-content");
+ for (var i = 0; i < tab_content.length; i++) {
+ tab_content[i].style.display = "none";
+ }
+ var tabs = document.getElementsByClassName("tab");
+ for (var i = 0; i < tabs.length; i++) {
+ tabs[i].className = tabs[i].className.replace(" active", "");
+ }
+
+ // Display selected tab's content, show tab as selected
+ document.getElementById(tab_id).style.display = "flex";
+ evt.currentTarget.className += " active";
+
+ mode = {"media_tab" : 0, "text_tab" : 1, "routes_tab" : 2}[tab_id];
+
+ update_content_editing_box();
+}
+
+function upload_media_files() {
+ var files = document.getElementById("media_upload").files;;
+
+ if (files.length == 0) {
+ alert("No files selected!");
+ return;
+ }
+
+ const formData = new FormData();
+ for (var i = 0; i < files.length; i++){
+ console.log(files[i]);
+ formData.append("files", files[i]);
+ }
+ formData.append("collection_id", collection_id);
+
+ fetch( "/editormediaupload", {
+ method: "POST",
+ credentials: "include",
+ body: formData
+ }).then((response) => response.json())
+ .then((json) => {
+ console.log('Gotcha');
+ }).catch((err) => {
+ console.log(err);
+ });
+}
+
+function edit_media_grid_element(media_dict) {
+ const media_div = media_divs[media_dict["id"]];
+ const name = media_div.querySelector("p");
+ name.innerText = media_dict["name"];
+
+ const icons = media_div.querySelectorAll("div.media div img");
+ icons[0].src = media_dict["longitude"] ? "static/img/yes-location.png" : "static/img/no-location.png";
+ icons[1].src = (media_dict["timestamp"] != "") ? "static/img/yes-datetime.png" : "static/img/no-datetime.png";
+
+ const timestamp = media_div.querySelector("p.media-timestamp");
+ timestamp.innerText = media_dict["timestamp"].replace("T", " ");
+}
+
+function add_media(media_dict){
+ // add data
+ collection_media[media_dict["id"]] = media_dict;
+
+ // add HTML element
+ const media_element = document.createElement('div');
+ media_element.className = "media";
+ media_element.dataset.id = media_dict["id"];
+
+ const img = document.createElement('img');
+ img.src = media_dict["thumbbig"];
+
+ const fn = document.createElement('p');
+ fn.innerText = media_dict["name"];
+
+ const info = document.createElement('div');
+ info.style = "display:flex; flex-direction:horizontal; margin:0; justify-content: center;";
+ const loc = document.createElement('img');
+ loc.src = media_dict["longitude"] ? "static/img/yes-location.png" : "static/img/no-location.png";
+ loc.style.width = "20px"; loc.style.height = "20px";
+ const dt = document.createElement('img');
+ dt.src = (media_dict["timestamp"] != "") ? "static/img/yes-datetime.png" : "static/img/no-datetime.png";
+ dt.style.width = "20px"; dt.style.height = "20px";
+ const dtext = document.createElement('p');
+ dtext.classList.add("media-timestamp")
+ dtext.innerText = media_dict["timestamp"].replace("T", " ");
+
+
+ info.appendChild(loc);
+ info.appendChild(dt);
+
+ media_element.appendChild(img);
+ media_element.appendChild(fn);
+ media_element.appendChild(dtext);
+ media_element.appendChild(info);
+
+
+ media_divs[media_dict["id"]] = media_element;
+
+ // add map icon
+ console.log(media_dict);
+ const media_icon = new Media_Icon({iconUrl : media_dict['thumbsmall']});
+ var lat = 0; var lng = 0;
+ if(media_dict['latitude'] && media_dict['longitude']) {
+ lat = media_dict['latitude'];
+ lng = media_dict['longitude'];
+ }
+ const media_marker = L.marker( [lat, lng], {icon:media_icon} ).on('click', function(e) { map_marker_clicked(media_dict["id"], 'media', e) });
+ media_markers_ref[media_dict["id"]] = media_marker;
+ media_markers_l.addLayer(media_marker);
+}
+
+function remove_media(media_id) {
+ for(var i = 0; i < selected_media_ids.length; i++) {
+ if (selected_media_ids[i] == media_id) {
+ selected_media_ids.pop(i);
+ break;
+ }
+ }
+ media_divs[media_id].remove();
+
+ media_markers_l.removeLayer(media_markers_ref[media_id]);
+ delete media_markers_ref[media_id];
+ delete media_divs[media_id];
+ delete collection_media[media_id];
+ update_content_editing_box();
+}
+
+// media grid stuff made by deepseek, not finished cleaning up
+document.addEventListener('DOMContentLoaded', function() {
+ const media_grid = document.getElementById('media_grid');
+
+ // Add click event listeners
+ media_grid.addEventListener('click', function(e) {
+ const media_element = e.target.closest('.media');
+ const isShiftKey = e.shiftKey;
+ const isCtrlKey = e.ctrlKey || e.metaKey; // metaKey for Mac Command key
+ if (!media_element) {
+ if(!isShiftKey && !isCtrlKey) clear_selection();
+ update_content_editing_box();
+ return;
+ }
+ const isVisible = function (ele, container) {
+ const { bottom, height, top } = ele.getBoundingClientRect();
+ const containerRect = container.getBoundingClientRect();
+
+ //console.log( ele.getBoundingClientRect());
+ //console.log(containerRect);
+
+ return top <= containerRect.top ? containerRect.top - top <= height : bottom - containerRect.bottom <= height;
+ };
+
+
+
+ const currentIndex = parseInt(media_element.dataset.index);
+ const current_media_id = media_element.dataset.id;
+
+ if (isShiftKey && last_selected_index !== -1) {
+ // Range selection with Shift key
+ select_range(last_selected_index, currentIndex, isCtrlKey);
+ } else if (isCtrlKey) {
+ // Toggle selection with Ctrl key
+ media_element.classList.toggle('selected');
+ selected_media_ids.push(current_media_id);
+ last_selected_index = currentIndex;
+ } else {
+ // Single selection
+ clear_selection();
+ media_element.classList.add('selected');
+ last_selected_index = currentIndex;
+ selected_media_ids.push(current_media_id);
+ }
+
+ update_content_editing_box();
+ if(!isVisible(media_element, media_element.parentElement))media_element.scrollIntoView();
+ });
+});
+
+// Clear all selections
+function clear_selection() {
+ selected_media_ids.length = 0; // clear selected media ids array... kind of strange way to do it but appears to be the most readable way of doing it
+ document.querySelectorAll('.media.selected').forEach(el => {
+ el.classList.remove('selected');
+ });
+ last_selected_index = -1;
+}
+
+// Select range of photos
+function select_range(start_index, end_index, additive) {
+ if (!additive) {
+ clear_selection();
+ }
+
+ const start = Math.min(start_index, end_index);
+ const end = Math.max(start_index, end_index);
+
+ for (let i = start; i <= end; i++) {
+ const photo = document.querySelector(`.media[data-index="${i}"]`);
+ if (photo) {
+ photo.classList.add('selected');
+ selected_media_ids.push(photo.dataset.id);
+ }
+ }
+}
+
+function update_media_grid() {
+ const media_grid = document.getElementById('media_grid');
+ while (media_grid.firstChild) {
+ media_grid.removeChild(media_grid.lastChild);
+ }
+ const hide_timestamp = document.getElementById("hide-timestamp").checked;
+ const hide_location = document.getElementById("hide-location").checked;
+ const sort_by = document.getElementById("sort-type").value;
+
+ const media_ids = [...Object.keys(media_divs)];
+ if (sort_by != "none") media_ids.sort( (a, b) => {
+ if(ascending) {
+ return collection_media[a][sort_by].localeCompare(collection_media[b][sort_by]);
+ } else {
+ return collection_media[b][sort_by].localeCompare(collection_media[a][sort_by]);
+ }
+ });
+
+ // remove hidden entries
+ for (var i = media_ids.length-1; i >= 0; i-- ) {
+ if (hide_timestamp && (collection_media[media_ids[i]]["timestamp"] != "")) media_ids.splice(i, 1);
+ else if (hide_location && (collection_media[media_ids[i]]["latitude"] && collection_media[media_ids[i]]["longitude"])) media_ids.splice(i, 1);
+ }
+
+ var i = 0;
+ for (var media_id of media_ids) {
+ const media_div = media_divs[media_id];
+ media_div.dataset.index = i;
+ media_grid.appendChild(media_div);
+ i += 1;
+ }
+}
+
+function update_content_editing_box() {
+ submit_edit_changes(); // make sure user changes are submitted
+
+ const content_box = document.getElementById("content_info");
+ const preview_box = document.getElementById("media-preview");
+ const video = document.getElementById("preview-video");
+ video.pause();
+ if(mode == 0) { // media editing mode
+ if(selected_media_ids.length == 0){
+ content_box.style.display="none";
+ preview_box.style.display="none";
+ return;
+ }
+
+ content_box.style.display="block";
+ preview_box.style.display="flex";
+
+ if(selected_media_ids.length == 1){
+ const selected_media = collection_media[selected_media_ids[0]];
+ for (const [key, value] of Object.entries(selected_media)) {
+ var field = document.getElementById("media_"+key);
+ if (field) field.value = value;
+ }
+ const location_text = document.getElementById("media_coords");
+ if(selected_media['latitude'] && selected_media['longitude']) {
+ map.panTo( [selected_media['latitude'], selected_media['longitude']] );
+ location_text.innerText = `(${selected_media['latitude']}, ${selected_media['longitude']})`;
+ } else {
+ location_text.innerText = "No location given! Press the picker button or 'C' to mark location.";
+ }
+
+ if (selected_media["is_video"]) {
+ const img = document.getElementById("preview-img");
+ video.src = selected_media["mediapath"];
+ img.style.display = "none";
+ video.style.display = "block";
+ } else {
+ const img = document.getElementById("preview-img");
+ img.src = selected_media["mediapath"];
+ video.style.display = "none";
+ img.style.display = "block";
+ }
+
+ } else { // multiple media selected
+ const fields = { ...collection_media[selected_media_ids[0]] };
+ for (var m_i = 1; m_i < selected_media_ids.length; m_i++) {
+ const selected_media = collection_media[selected_media_ids[ m_i ]];
+ for (const [key, value] of Object.entries(selected_media)) {
+ if( value != fields[key] ) fields[key] = "< ... >";
+ }
+ }
+
+ for (const [key, value] of Object.entries(fields)) {
+ var field = document.getElementById("media_"+key);
+ if (field) field.value = value;
+ }
+ const location_text = document.getElementById("media_coords");
+ if(fields['latitude'] && fields['longitude'] && Number(fields['latitude']) && Number(fields['longitude'])) {
+ map.panTo( [fields['latitude'], fields['longitude']]);
+ location_text.innerText = `(${fields['latitude']}, ${fields['longitude']})`;
+ } else if ( !(fields['latitude'] && fields['longitude']) )
+ location_text.innerText = "No location given! Press the picker button or 'C' to mark location.";
+ else {
+ location_text.innerText = "< ... >";
+ }
+ }
+ }
+}
+
+function picker_clicked() {
+ const picking_style = document.createElement('style');
+ picking_style.innerHTML = '*{cursor: crosshair;}';
+ picking_style.id = 'picking-style';
+ document.head.appendChild(picking_style);
+
+ L.DomUtil.addClass(map._container, "crosshair-cursor-enabled");
+
+ const media_boxes = document.getElementsByClassName("media");
+ for(var i = 0; i < media_boxes.length; i++) {
+ media_boxes[i].classList.add('no-hover');
+ }
+ const tabs = document.getElementsByClassName("tab-header");
+ for(var i = 0; i < tabs.length; i++) {
+ tabs[i].classList.add('no-hover');
+ }
+
+ map.removeLayer(media_markers_l);
+
+ is_picking_location = true;
+}
+
+function disable_picking() {
+ is_picking_location = false;
+ document.getElementById('picking-style').remove();
+ L.DomUtil.removeClass(map._container, "crosshair-cursor-enabled");
+
+ const media_boxes = document.getElementsByClassName("media");
+ for(var i = 0; i < media_boxes.length; i++) {
+ media_boxes[i].classList.remove('no-hover');
+ }
+
+ const tabs = document.getElementsByClassName("tab-header");
+ for(var i = 0; i < tabs.length; i++) {
+ tabs[i].classList.remove('no-hover');
+ }
+ map.addLayer(media_markers_l);
+}
+
+function handle_map_click(latitude, longitude) {
+ if(!is_picking_location) return;
+ map.addLayer(media_markers_l);
+ edit_media_info({"latitude" : latitude, "longitude" : longitude});
+ disable_picking();
+}
+
+function map_marker_clicked(id, type, e) {
+ clear_selection();
+ if (type === "media") {
+ const media = document.querySelector(`.media[data-id="${id}"]`);
+ if (media) {
+ media.classList.add('selected');
+ selected_media_ids.push(media.dataset.id);
+ last_selected_index = parseInt(media.dataset.index);
+ media.scrollIntoView();
+ } else { // media filtered
+ document.getElementById("hide-timestamp").checked = false;
+ document.getElementById("hide-location").checked = false;
+ update_media_grid();
+ const media = document.querySelector(`.media[data-id="${id}"]`);
+ media.classList.add('selected');
+ selected_media_ids.push(media.dataset.id);
+ last_selected_index = parseInt(media.dataset.index);
+ media.scrollIntoView();
+ }
+ update_content_editing_box();
+ }
+}
+
+function open_media_preview() {
+ const modal = document.getElementById('media-preview-modal');
+ const preview_img = document.getElementById("preview-img");
+ const modal_media = document.getElementById("modal-img");
+
+ modal.style.display = "block";
+ modal_media.src = preview_img.src;
+ media_modal_open = true;
+}
+
+function close_media_preview() {
+ const modal = document.getElementById('media-preview-modal');
+ modal.style.display = "none";
+ media_modal_open = false;
+}
+
+function open_share_modal() {
+ update_share_info();
+ var modal = document.getElementById('share-modal');
+ share_modal_open = true;
+ modal.style.display = "block";
+}
+
+function close_share_modal() {
+ var modal = document.getElementById('share-modal');
+ share_modal_open = false;
+ modal.style.display = "none";
+}
+
+function update_share_info() {
+ const publicity = document.getElementById("visibility-dropdown");
+ publicity.value = collection_perms["public"] ? "public" : "private";
+
+ const user_section = document.getElementById("shared-users");
+ while (user_section.firstChild)
+ user_section.removeChild(user_section.firstChild);
+
+ const editor_option = document.createElement("option");
+ editor_option.innerText = "Editor";
+ editor_option.value = "editor";
+ const viewer_option = document.createElement("option");
+ viewer_option.innerText = "Viewer";
+ viewer_option.value = "viewer";
+
+ for (var t = 0; t < 2; t++) {
+ const user_type = t == 0 ? "editor" : "viewer";
+ for (var i = 0; i < collection_perms[user_type+"s"].length; i++) {
+ const user_email_str = collection_perms[user_type+"s"][i];
+ const user_email = document.createElement("p");
+ user_email.innerText = collection_perms[user_type+"s"][i];
+ user_email.style.margin = "0";
+
+ const user_permissions = document.createElement("select");
+ const e = editor_option.cloneNode(true);
+ const v = viewer_option.cloneNode(true);
+ user_permissions.appendChild(e);
+ user_permissions.appendChild(v);
+ user_permissions.value = user_type;
+ user_permissions.onchange = () => { edit_permissions(user_email_str, user_permissions.value) }
+
+ const user_unshare = document.createElement("p");
+ user_unshare.innerText = "Unshare";
+ user_unshare.classList.add("user-unshare-button");
+ user_unshare.onclick = function () { edit_permissions(user_email_str, ""); }
+
+ user_section.appendChild(user_email);
+ user_section.appendChild(user_permissions);
+ user_section.appendChild(user_unshare);
+ }
+ }
+}
+
+function open_collection_modal() {
+ update_collection_info();
+ var modal = document.getElementById('collection-modal');
+ collection_modal_open = true;
+ modal.style.display = "block";
+}
+
+function close_collection_modal() {
+ var modal = document.getElementById('collection-modal');
+ collection_modal_open = false;
+ modal.style.display = "none";
+}
+
+function update_collection_info() {
+ document.getElementById("collection-title-field").value = collection_info["title"];
+ document.getElementById("collection-subtitle-field").value = collection_info["subtitle"];
+ document.getElementById("collection-info-field").value = collection_info["info"];
+}
+
+function mark_info_change(field) {
+ changes[field] = true;
+}
+
+function submit_edit_changes() {
+ console.log(changes);
+ var edits = {};
+ for (const [field, was_changed] of Object.entries(changes)) {
+ if (was_changed) {
+ const new_val = document.getElementById("media_"+field).value;
+ if (new_val != collection_media[selected_media_ids[0]][field]) edits[field] = new_val;
+ }
+ changes[field] = false; // reset dictionary
+ }
+ if(Object.keys(edits).length > 0) {
+ edit_media_info(edits);
+ }
+}
+
+// communicate
+// with
+// the
+// server
+
+// run every x seconds to get latest info from server
+function request_latest_info(){
+ console.log("requesting update");
+ function handleLatestInfo(json){
+ console.log(json);
+ if(json['status'] != "OK") return; // ADD ERROR NOTIF ON MENU BAR
+
+ if(!json['update']) return; // no changes
+
+ let new_collection = json['collection'];
+ let new_media_ids = [];
+ for(var i = 0; i < new_collection['media'].length; i++) {
+ const media_id = new_collection['media'][i]['id'];
+ new_media_ids.push(media_id);
+ if(collection_media[media_id] == undefined) {
+ add_media(new_collection['media'][i]);
+ } else { // update existing
+ collection_media[media_id] = new_collection['media'][i]
+ edit_media_grid_element(collection_media[media_id]);
+ if(collection_media[media_id]['latitude'] && collection_media[media_id]['longitude'])
+ media_markers_ref[media_id].setLatLng([collection_media[media_id]['latitude'], collection_media[media_id]['longitude']]);
+ }
+ }
+ let to_be_removed = [];
+ for (const [key, _] of Object.entries(collection_media)) {
+ if (!new_media_ids.includes(key)) to_be_removed.push(key);
+ }
+ console.log(to_be_removed);
+ for (var i = 0; i < to_be_removed.length; i++){
+ remove_media(to_be_removed[i]);
+ }
+
+ // update permissions info
+ collection_perms["owner"] = new_collection["owner"];
+ collection_perms["editors"] = new_collection["editors"];
+ collection_perms["viewers"] = new_collection["viewers"];
+ collection_perms["public"] = new_collection["public"];
+ if(share_modal_open) update_share_info();
+
+ document.getElementById("collection-title").innerText = new_collection["title"];
+ collection_info["title"] = new_collection["title"];
+ collection_info["subtitle"] = new_collection["subtitle"];
+ collection_info["info"] = new_collection["info"];
+ if(collection_modal_open) update_share_info();
+
+ update_media_grid(); // make smarter later
+ update_content_editing_box();
+ latest_timestamp = new_collection["last_edited"];
+
+ }
+ fetch(host+'/editorgetlatestinfo', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ "collection" : collection_id, "last_updated" : latest_timestamp })})
+ .then((response) => response.json())
+ .then((json) => handleLatestInfo(json));
+}
+
+function delete_media() {
+ if(!confirm("Are you sure you want to delete these pieces of media? This cannot be undone!")) return;
+
+ fetch(host+'/editordeletemedia', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ "collection" : collection_id, "to_be_removed" : selected_media_ids })})
+ .then((response) => response.json())
+ .then((json) => { clear_selection(); request_latest_info(); });
+}
+
+function edit_media_info(changes) {
+ console.log("edit");
+ const data = [];
+ for (var i = 0; i < selected_media_ids.length; i++) {
+ data.push({"media_id" : selected_media_ids[i], "changes" : changes})
+ }
+ fetch(host+'/editoreditmedia', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ "collection" : collection_id, "edits" : data })})
+ .then((response) => response.json())
+ .then((json) => {console.log(json); request_latest_info();});
+}
+
+function update_visibility() {
+ const visibility = document.getElementById("visibility-dropdown").value == "public" ? true : false;
+ const data = { "collection" : collection_id, "public" : visibility };
+ fetch(host+'/editorshare', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(data)})
+ .then((response) => response.json())
+ .then((json) => {console.log(json); request_latest_info();});
+}
+
+function add_shared_user() {
+ const user_email_e = document.getElementById("share-email");
+ const permission_e = document.getElementById("share-permissions");
+ edit_permissions(user_email_e.value, permission_e.value);
+
+ user_email_e.value = ""; // reset email
+}
+
+function edit_permissions(user_email, permission) {
+ console.log(user_email);
+ console.log(permission);
+ const data = { "collection" : collection_id, "user_email" : user_email, "perm" : permission };
+
+ fetch(host+'/editorshare', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(data)})
+ .then((response) => response.json())
+ .then((json) => {console.log(json); request_latest_info();});
+}
+
+function collection_info_updated(field) {
+ const field_input = document.getElementById('collection-'+field+'-field');
+ if(field_input) {
+ edit_collection_info(field, field_input.value);
+ }
+}
+
+function edit_collection_info(field, value) {
+ const edits = {};
+ edits[field] = value;
+ const data = { "collection" : collection_id, "edits" : edits };
+
+ fetch(host+'/editorcollectioninfo', {
+ method: "POST",
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(data)})
+ .then((response) => response.json())
+ .then((json) => {console.log(json); request_latest_info();});
+}
+
+function toggle_sort_direction(){
+ ascending = !ascending;
+ document.getElementById("sort-direction").innerText = ascending ? "Ascending" : "Descending";
+ update_media_grid();
+} \ No newline at end of file