diff --git a/app/config/constants.php b/app/config/constants.php index 2f59171..a51f251 100644 --- a/app/config/constants.php +++ b/app/config/constants.php @@ -39,7 +39,7 @@ if ( ! defined( 'CONFIG_DIRECTORY' ) ) { define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' ); # Tempus Project Core define( 'APP_NAME', 'All The Bookmarks'); -define( 'TP_DEFAULT_LOGO', 'images/logo.png'); +define( 'TP_DEFAULT_LOGO', 'images/logo180.png'); // Check define( 'MINIMUM_PHP_VERSION', 8.1); // Cookies diff --git a/app/css/main.css b/app/css/main.css index 7f64ee8..3fb5bb7 100644 --- a/app/css/main.css +++ b/app/css/main.css @@ -310,3 +310,8 @@ body { /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ background: linear-gradient(to right, #2c2c2c, #1e1e1e, #1e1e1e); } + +.bookmark-card.dragging { + opacity: 0.7; + cursor: move; /* Show a move cursor when dragging */ + } \ No newline at end of file diff --git a/app/plugins/bookmarks/controllers/bookmarks.php b/app/plugins/bookmarks/controllers/bookmarks.php index 27a1aa6..aa45f57 100644 --- a/app/plugins/bookmarks/controllers/bookmarks.php +++ b/app/plugins/bookmarks/controllers/bookmarks.php @@ -56,6 +56,9 @@ class Bookmarks extends Controller { Components::set( 'userFolderTabs', $userFolderTabsView ); Components::set( 'SITE_URL', Routes::getAddress() ); Views::raw( $tabsView ); + Components::append( 'TEMPLATE_JS_INCLUDES', Template::parse('' ) ); + $options = Views::simpleView( 'bookmarks.nav.viewOptions' ); + Components::set( 'VIEW_OPTIONS', $options ); } public function index() { @@ -71,6 +74,7 @@ class Bookmarks extends Controller { $folderObject->ID = $folder->ID; $folderObject->title = $folder->title; $folderObject->color = $folder->color; + $folderObject->uuid = $folder->uuid; $folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks ); $panelArray[] = $folderObject; } diff --git a/app/plugins/bookmarks/js/bookmarks.js b/app/plugins/bookmarks/js/bookmarks.js new file mode 100644 index 0000000..7dd4b36 --- /dev/null +++ b/app/plugins/bookmarks/js/bookmarks.js @@ -0,0 +1,186 @@ +document.addEventListener('DOMContentLoaded', () => { + // Handle all bootstrap popover inits + const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]') + const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl)) + + const masonryContainer = document.querySelector('[data-masonry]'); + if ( ! masonryContainer ) { + return; + } + const masonryInstance = new Masonry(masonryContainer, { + columnHeight: '.accordion', + percentPosition: true + }); + const updateMasonryLayout = () => masonryInstance.layout(); + + masonryContainer.addEventListener('hidden.bs.collapse', updateMasonryLayout); + masonryContainer.addEventListener('shown.bs.collapse', updateMasonryLayout); + + const observer = new MutationObserver(() => { + updateMasonryLayout(); + }); + + // Observe all cards for changes in the DOM + document.querySelectorAll('.card').forEach((card) => { + observer.observe(card, { childList: true, subtree: true }); + }); + + // Initialize all toggle functions + toggleVisibility('editModeSwitch', 'edit-mode'); + toggleVisibility('showArchivedSwitch', 'link-archived'); + toggleVisibility('showHiddenSwitch', 'link-hidden'); + toggleVisibility('archiveButtonSwitch', 'btn-archive'); + toggleVisibility('visibilityButtonSwitch', 'btn-hideshow'); + toggleVisibility('privacyButtonSwitch', 'btn-publish'); + toggleVisibility('addButtonSwitch', 'btn-addlink'); + toggleVisibility('shareButtonSwitch', 'btn-share'); +}); + +// Function to handle showing or hiding elements based on the checkbox state +function toggleVisibility(switchId, className) { + const switchElement = document.getElementById(switchId); + const elementsToToggle = document.querySelectorAll(`.${className}`); + + // Listen for changes to the checkbox + switchElement.addEventListener('change', () => { + if (switchElement.checked) { + elementsToToggle.forEach(element => { + element.style.display = ''; // Show the element (default display) + }); + } else { + elementsToToggle.forEach(element => { + element.style.display = 'none'; // Hide the element + }); + } + }); + + // Trigger the toggle initially to set the correct visibility on page load + switchElement.dispatchEvent(new Event('change')); +} +document.addEventListener('DOMContentLoaded', function () { + const bookmarkSort = document.getElementById('bookmarkSort'); + let draggingElement = null; + let placeholder = null; + let initialX = 0; + let initialY = 0; + let offsetX = 0; + let offsetY = 0; + + // Function to handle the drag start + const handleDragStart = (e, element) => { + draggingElement = element; + + // Create a placeholder to maintain layout + placeholder = document.createElement('div'); + placeholder.style.height = `${draggingElement.offsetHeight}px`; + placeholder.style.marginBottom = getComputedStyle(draggingElement).marginBottom; + placeholder.classList.add('placeholder'); + draggingElement.parentNode.insertBefore(placeholder, draggingElement); + + const rect = element.getBoundingClientRect(); + initialX = e.clientX; + initialY = e.clientY; + offsetX = e.clientX - rect.left; + offsetY = e.clientY - rect.top; + + // Prevent the element from moving in the normal flow + element.classList.add('dragging'); + element.style.position = 'absolute'; + draggingElement.style.width = `${rect.width}px`; // Preserve width + draggingElement.style.height = `${rect.height}px`; // Preserve height + element.style.zIndex = 1000; // Bring the element on top of others + element.style.left = `${rect.left}px`; + element.style.top = `${rect.top}px`; + + e.preventDefault(); + }; + + // Function to handle dragging movement + const handleDragMove = (e) => { + if (draggingElement) { + const dx = e.clientX - initialX + offsetX; + const dy = e.clientY - initialY + offsetY; + + draggingElement.style.left = `${dx}px`; + draggingElement.style.top = `${dy}px`; + } + }; + + // Function to handle the drag end + const handleDragEnd = () => { + if (draggingElement) { + const rect = draggingElement.getBoundingClientRect(); + + // Reset the position styles of the dragged element + draggingElement.style.position = ''; + draggingElement.style.zIndex = ''; // Reset z-index + draggingElement.style.left = ''; + draggingElement.style.top = ''; + draggingElement.classList.remove('dragging'); + + // Re-insert the element back into the DOM properly + const closestElement = getClosestElement(rect.left, rect.top); + console.error(closestElement.id); + + if (closestElement) { + bookmarkSort.insertBefore(draggingElement, closestElement); + console.log( 'insertBefore' ); + } else { + bookmarkSort.appendChild(draggingElement); + console.log( 'append' ); + } + + // Reorder the elements after the drag ends + reorderElements(); + draggingElement = null; + } + }; + + // Function to reorder the elements inside the container + const reorderElements = () => { + const elements = Array.from(bookmarkSort.children); + const sortedIds = elements.map(element => element.id); + console.log('New order:', sortedIds); + }; + + // Function to handle the drop event + const handleDrop = (e) => { + e.preventDefault(); + }; + + // Helper function to find the closest element based on mouse position + const getClosestElement = (x, y) => { + const elements = Array.from(bookmarkSort.children).filter( + (el) => el !== placeholder && el !== draggingElement + ); + + let closest = null; + let closestDistance = Number.POSITIVE_INFINITY; + + elements.forEach((child) => { + const rect = child.getBoundingClientRect(); + const distance = Math.abs(rect.top - y); + + if (distance < closestDistance) { + closestDistance = distance; + closest = child; + } + }); + + return closest; + }; + + // Attach event listeners to all .card-header elements for dragging + Array.from(document.querySelectorAll('.mover-arrow')).forEach(cardHeader => { + cardHeader.addEventListener('mousedown', (e) => handleDragStart(e, cardHeader.closest('.bookmark-card'))); + }); + + // Handle the dragging process + document.addEventListener('mousemove', handleDragMove); + document.addEventListener('mouseup', handleDragEnd); + bookmarkSort.addEventListener('dragover', handleDrop); // Listen for the drop event to update the order +}); + + + + \ No newline at end of file diff --git a/app/plugins/bookmarks/models/bookmarks.php b/app/plugins/bookmarks/models/bookmarks.php index 9d289fa..6e5518d 100644 --- a/app/plugins/bookmarks/models/bookmarks.php +++ b/app/plugins/bookmarks/models/bookmarks.php @@ -322,15 +322,6 @@ class Bookmarks extends DatabaseModel { return $finalUrl; - - - - - - - - - // $headers = get_headers( $url, 1 ); $headers = @get_headers($url, 1); if ( $headers === false ) { @@ -358,35 +349,33 @@ class Bookmarks extends DatabaseModel { $instance->iconHtml = ''; } else { if (strpos($instance->icon, 'http') !== false) { - $instance->iconHtml = ''; + $instance->iconHtml = ''; } else { - $instance->iconHtml = ''; + $instance->iconHtml = ''; } } if ( $instance->privacy == 'private' ) { $instance->privacyBadge = 'Private'; - } else { - $instance->privacyBadge = 'Public'; - } - - if ( $instance->privacy == 'private' ) { $instance->publish = ' '; } else { + $instance->privacyBadge = 'Public'; $instance->publish = ' '; } if ( empty( $instance->hiddenAt ) ) { + $instance->hidden_class = ''; $instance->hideBtn = ' '; } else { + $instance->hidden_class = 'link-hidden'; $instance->hideBtn = ' @@ -394,11 +383,13 @@ class Bookmarks extends DatabaseModel { } if ( empty( $instance->archivedAt ) ) { + $instance->archived_class = ''; $instance->archiveBtn = ' '; } else { + $instance->archived_class = 'link-archived'; $instance->archiveBtn = ' diff --git a/app/plugins/bookmarks/views/components/bookmarkListPanel.html b/app/plugins/bookmarks/views/components/bookmarkListPanel.html index 8d10a9d..d195e51 100644 --- a/app/plugins/bookmarks/views/components/bookmarkListPanel.html +++ b/app/plugins/bookmarks/views/components/bookmarkListPanel.html @@ -1,10 +1,31 @@ {LOOP} -
+
-
- {title} + + + +
    @@ -12,12 +33,12 @@
diff --git a/app/plugins/bookmarks/views/components/bookmarkListRows.html b/app/plugins/bookmarks/views/components/bookmarkListRows.html index 5410aff..31d43b8 100644 --- a/app/plugins/bookmarks/views/components/bookmarkListRows.html +++ b/app/plugins/bookmarks/views/components/bookmarkListRows.html @@ -1,14 +1,30 @@ - {LOOP} -
  • +
  • {iconHtml} {title} - {hideBtn} - {archiveBtn} - {publish} - - + {hideBtn} + {archiveBtn} + {publish} + + + + + +
  • {/LOOP} diff --git a/app/plugins/bookmarks/views/components/shareListPanel.html b/app/plugins/bookmarks/views/components/shareListPanel.html index 1caabdc..a9b1fbc 100644 --- a/app/plugins/bookmarks/views/components/shareListPanel.html +++ b/app/plugins/bookmarks/views/components/shareListPanel.html @@ -9,7 +9,7 @@ {privacyBadge} {title} - +
    diff --git a/app/plugins/bookmarks/views/components/shareListRows.html b/app/plugins/bookmarks/views/components/shareListRows.html index 02337e8..955d3a9 100644 --- a/app/plugins/bookmarks/views/components/shareListRows.html +++ b/app/plugins/bookmarks/views/components/shareListRows.html @@ -4,7 +4,7 @@ {title}{privacyBadge} {publish} - +