From 898f7479c96e1e9ce3625786f99b5c9d3e066339 Mon Sep 17 00:00:00 2001
From: Kevin Veen-Birkenbach <kevin@veen.world>
Date: Tue, 18 Mar 2025 12:50:14 +0100
Subject: [PATCH] Added scrollbar draft

---
 README.md                           |   2 +-
 app/static/css/custom_scrollbar.css |  33 +++++++++
 app/static/js/custom_scrollbar.js   | 111 ++++++++++++++++++++++++++++
 app/templates/moduls/base.html.j2   |  19 ++++-
 4 files changed, 162 insertions(+), 3 deletions(-)
 create mode 100644 app/static/css/custom_scrollbar.css
 create mode 100644 app/static/js/custom_scrollbar.js

diff --git a/README.md b/README.md
index 8d52556..1c39b85 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ Access the application locally at [http://127.0.0.1:5000](http://127.0.0.1:5000)
    docker-compose up --build
    ```
 
-4. **Access your portfolio:** Open your browser and navigate to `http://localhost:5000`.
+4. **Access your portfolio:** Open your browser and navigate to [http://localhost:5000](http://localhost:5000).
 
 ## Configuration Guide 🔧
 
diff --git a/app/static/css/custom_scrollbar.css b/app/static/css/custom_scrollbar.css
new file mode 100644
index 0000000..d8e33f8
--- /dev/null
+++ b/app/static/css/custom_scrollbar.css
@@ -0,0 +1,33 @@
+/* Den scroll-container so einstellen, dass er nur vertikal scrollt */
+.scroll-container {
+    overflow-y: auto;
+    overflow-x: hidden;
+    /* Native Scrollbar ausblenden */
+    scrollbar-width: none; /* Firefox */
+  }
+  .scroll-container::-webkit-scrollbar {
+    display: none; /* WebKit */
+  }
+  
+  /* Das benutzerdefinierte Scrollbar-Element fixiert am rechten Rand */
+  #custom-scrollbar {
+    position: fixed;
+    top: 0;
+    right: 0;
+    width: 8px;
+    height: 100vh;
+    background: transparent;
+    /* pointer-events NICHT ausschalten, damit die Scrollbar bedienbar bleibt */
+    transition: opacity 0.3s ease;
+    opacity: 1; /* dauerhaft sichtbar, wenn benötigt */
+  }
+  
+  /* Der Thumb der Scrollbar */
+  #scroll-thumb {
+    position: absolute;
+    top: 0;
+    width: 100%;
+    background-color: rgba(0, 0, 0, 0.2);
+    border-radius: 4px;
+  }
+  
\ No newline at end of file
diff --git a/app/static/js/custom_scrollbar.js b/app/static/js/custom_scrollbar.js
new file mode 100644
index 0000000..5084c4d
--- /dev/null
+++ b/app/static/js/custom_scrollbar.js
@@ -0,0 +1,111 @@
+function adjustScrollContainerHeight() {
+  // Elemente ermitteln
+  const headerEl = document.querySelector('header');
+  const navEl = document.querySelector('nav');
+  const footerEl = document.querySelector('footer');
+  const mainEl = document.getElementById('main');
+  if (!mainEl) return;
+  const scrollContainer = mainEl.querySelector('.scroll-container');
+  if (!scrollContainer) return;
+  
+  let siblingsHeight = 0;
+  
+  if (headerEl) {
+    const headerRect = headerEl.getBoundingClientRect();
+    siblingsHeight += headerRect.height;
+  }
+  if (navEl) {
+    const navRect = navEl.getBoundingClientRect();
+    siblingsHeight += navRect.height*2;
+  }
+  if (footerEl) {
+    const footerRect = footerEl.getBoundingClientRect();
+    siblingsHeight += footerRect.height;
+  }
+  
+  // Verfügbare Höhe berechnen: Fensterhöhe minus Höhe der Geschwister
+  const availableHeight = window.innerHeight - siblingsHeight;
+  
+  // Setze die max-Höhe für den Scroll-Container
+  scrollContainer.style.maxHeight = availableHeight + 'px';
+  scrollContainer.style.overflowY = 'auto';
+  scrollContainer.style.overflowX = 'hidden';
+}
+
+window.addEventListener('load', adjustScrollContainerHeight);
+window.addEventListener('resize', adjustScrollContainerHeight);
+
+// 2. Aktualisiert den Thumb (Größe und Position) der benutzerdefinierten Scrollbar
+function updateCustomScrollbar() {
+  const scrollContainer = document.querySelector('.scroll-container');
+  const thumb = document.getElementById('scroll-thumb');
+  const customScrollbar = document.getElementById('custom-scrollbar');
+  if (!scrollContainer || !thumb || !customScrollbar) return;
+  
+  const contentHeight = scrollContainer.scrollHeight;
+  const containerHeight = scrollContainer.clientHeight;
+  const scrollTop = scrollContainer.scrollTop;
+  
+  // Berechne die Thumb-Höhe (mindestens 20px)
+  let thumbHeight = (containerHeight / contentHeight) * containerHeight;
+  thumbHeight = Math.max(thumbHeight, 20);
+  thumb.style.height = thumbHeight + 'px';
+  
+  // Berechne die Position des Thumbs
+  const maxScrollTop = contentHeight - containerHeight;
+  const maxThumbTop = containerHeight - thumbHeight;
+  const thumbTop = maxScrollTop ? (scrollTop / maxScrollTop) * maxThumbTop : 0;
+  thumb.style.top = thumbTop + 'px';
+  
+  // Zeige die Scrollbar, falls der Inhalt überläuft, sonst ggf. ausblenden
+  customScrollbar.style.opacity = contentHeight > containerHeight ? '1' : '0';
+}
+
+// Aktualisiere den Thumb bei Scrollen des Containers
+const scrollContainer = document.querySelector('.scroll-container');
+if (scrollContainer) {
+  scrollContainer.addEventListener('scroll', updateCustomScrollbar);
+}
+window.addEventListener('resize', updateCustomScrollbar);
+window.addEventListener('load', updateCustomScrollbar);
+
+// 3. Interaktivität: Ermögliche Drag & Drop des Scroll-Thumbs
+let isDragging = false;
+let dragStartY = 0;
+let scrollStartY = 0;
+
+const thumb = document.getElementById('scroll-thumb');
+
+if (thumb) {
+  thumb.addEventListener('mousedown', function(e) {
+    isDragging = true;
+    dragStartY = e.clientY;
+    scrollStartY = scrollContainer.scrollTop;
+    e.preventDefault();
+  });
+}
+
+document.addEventListener('mousemove', function(e) {
+  if (!isDragging) return;
+  const containerHeight = scrollContainer.clientHeight;
+  const contentHeight = scrollContainer.scrollHeight;
+  const thumbHeight = thumb.offsetHeight;
+  
+  const maxScrollTop = contentHeight - containerHeight;
+  const maxThumbTop = containerHeight - thumbHeight;
+  
+  const deltaY = e.clientY - dragStartY;
+  // Berechne neuen Thumb-Top-Wert
+  let newThumbTop = (scrollStartY / maxScrollTop) * maxThumbTop + deltaY;
+  newThumbTop = Math.max(0, Math.min(newThumbTop, maxThumbTop));
+  
+  // Berechne den neuen Scrollwert anhand der Thumb-Position
+  const newScrollTop = (newThumbTop / maxThumbTop) * maxScrollTop;
+  scrollContainer.scrollTop = newScrollTop;
+});
+
+document.addEventListener('mouseup', function(e) {
+  if (isDragging) {
+    isDragging = false;
+  }
+});
diff --git a/app/templates/moduls/base.html.j2 b/app/templates/moduls/base.html.j2
index 16c20b7..8a87eaf 100644
--- a/app/templates/moduls/base.html.j2
+++ b/app/templates/moduls/base.html.j2
@@ -14,7 +14,8 @@
         <script src="https://kit.fontawesome.com/56f96da298.js" crossorigin="anonymous"></script>
         <!-- Markdown -->
         <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
-        <link rel="stylesheet" href="static/css/default.css">
+        <link rel="stylesheet" href="{{ url_for('static', filename='css/default.css') }}">
+        <link rel="stylesheet" href="{{ url_for('static', filename='css/custom_scrollbar.css') }}">
     </head>
     <body>
         <div class="container">
@@ -26,7 +27,20 @@
             </header>
             {% set menu_type = "header" %}
             {% include "moduls/navigation.html.j2"%}
-            {% block content %}{% endblock %}
+
+<main id="main" style="position: relative; box-shadow: 0 0 20px rgba(0,0,0,0.3); overflow: visible;">
+  <div class="scroll-container">
+    <!-- Hier kommt dein Hauptinhalt -->
+    {% block content %}{% endblock %}
+  </div>
+</main>
+
+<!-- Custom scrollbar element fixiert am rechten Rand -->
+<div id="custom-scrollbar">
+  <div id="scroll-thumb"></div>
+</div>
+
+
             {% set menu_type = "footer" %}
             {% include "moduls/navigation.html.j2" %}
             <footer class="footer">
@@ -43,5 +57,6 @@
         <script src="{{ url_for('static', filename='js/modal.js') }}"></script>
         <script src="{{ url_for('static', filename='js/navigation.js') }}"></script>
         <script src="{{ url_for('static', filename='js/tooltip.js') }}"></script>
+        <script src="{{ url_for('static', filename='js/custom_scrollbar.js') }}"></script>
     </body>
 </html>
\ No newline at end of file