From e613e58c46b8ea21e86b1e27c5b3d631d3ab9b1d Mon Sep 17 00:00:00 2001
From: Gabriel <gabriel@libresolutions.network>
Date: Mon, 21 Nov 2022 13:47:10 -0500
Subject: [PATCH] video and audio updates

---
 layouts/shortcodes/audio.html     |  69 ++++++--
 layouts/shortcodes/video.html     | 283 ++++++++++++++++++++----------
 layouts/shortcodes/yesterweb.html |   3 -
 static/css/theme.css              |   2 +-
 static/res/expand.svg             |  71 ++++++++
 static/res/loop.svg               |  60 +++++++
 static/res/pause.svg              |  63 +++++++
 static/res/play.svg               |  54 ++++++
 static/res/shrink.svg             |  71 ++++++++
 9 files changed, 567 insertions(+), 109 deletions(-)
 delete mode 100644 layouts/shortcodes/yesterweb.html
 create mode 100644 static/res/expand.svg
 create mode 100644 static/res/loop.svg
 create mode 100644 static/res/pause.svg
 create mode 100644 static/res/play.svg
 create mode 100644 static/res/shrink.svg

diff --git a/layouts/shortcodes/audio.html b/layouts/shortcodes/audio.html
index 876fe4a..a8e3b01 100644
--- a/layouts/shortcodes/audio.html
+++ b/layouts/shortcodes/audio.html
@@ -1,8 +1,4 @@
 <style>
-    .media-container {
-        width: 90%;
-    }
-
     .audio-player {
         display: flex;
         flex-direction: row;
@@ -15,13 +11,51 @@
     .media-seek {
         width: 100%;
     }
+    .audio-player{
+    border: 0.15rem solid var(--theme-accent);
+    padding:0.5rem;
+    border-radius: 0.5rem;
+    color:var(--theme-accent);
+}
+.audio-player>*{
+    margin:5px;
+}
+
+.audio-player select, .audio-player button{
+    background-color: transparent;
+    border-color: var(--theme-accent);
+    color:var(--theme-accent);
+    border-radius: 3px;
+    padding:0.5rem;
+}
+
+.icon svg{
+    width:2.25rem;
+    z-index: -1;
+    background-color: transparent;
+    pointer-events: none;
+}
+.icon path{
+    stroke:var(--theme-accent);    
+    fill:var(--theme-accent);
+}
+
+@keyframes spin-icon {
+    0%{rotate:0;}
+    100%{rotate:360deg;}  
+}
+.spin{
+    animation:spin-icon 3s linear infinite;
+}
 </style>
 <div class="media-container">
     <div class="audio-player">
-        <audio onloadedmetadata="setup_audio_metadata(event)" ontimeupdate="setup_audio_metadata(event)">
+        <audio onended="audio_end(event)" onloadedmetadata="setup_audio_metadata(event)" ontimeupdate="setup_audio_metadata(event)">
             <source src='{{.Site.BaseURL}}{{.Get "src" }}'>
         </audio>
-        <button onclick="toggle_play_audio(event)">Play</button>
+        <div class="icon" onclick="toggle_play_audio(event)">
+            <svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 90 90" enable-background="new 0 0 90 90" xml:space="preserve"><path d="M45,6.421c21.273,0,38.579,17.306,38.579,38.579S66.273,83.578,45,83.578c-21.273,0-38.579-17.306-38.579-38.579  S23.727,6.421,45,6.421 M45,0C20.148,0,0,20.146,0,44.999s20.148,44.999,45,44.999c24.852,0,45-20.146,45-44.999S69.852,0,45,0L45,0  z M65.5,44.999l-31.5-18v36L65.5,44.999z"></path></svg>
+        </div>
         <input class="media-seek" type="range" onchange="update_audio_time(event)" value="0">
         <select onchange="update_audio_speed(event)">
             <option value="1" selected>1x</option>
@@ -33,8 +67,16 @@
         <div class="audio-preview">
         </div>
         <p><span class="audio-currentTime"></span><span class="audio-duration"></span></p>
-        <button onclick="toggle_loop_audio(event)">Loop</button>
+        <div class="icon" onclick="toggle_loop_audio(event)">
+            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><path d="M25.9,45.9c0,0-0.1,0-0.1,0l-9.2,0c-0.4,0-2.1-0.1-3.1-1.5c-0.4-0.6-0.9-1.6-0.5-3C16.4,28.1,24.4,19,36.7,14.6  c15-5.4,28.9-2.2,40.7,9.4l5-4.8c0.4-0.3,1.3-1.1,2.4-1.1c0.9,0,2.4,0.6,2.4,2.8v21.8c0,1.6-1.1,2.9-2.8,3.2c-0.1,0-0.3,0-0.4,0  H62.4c-0.1,0-0.1,0-0.2,0c-0.5-0.1-2.1-0.3-2.6-1.8c-0.2-0.6-0.4-1.7,0.8-2.9l5.3-5.4c-4.8-5.2-10.6-7.6-17.2-7.1  c-9.1,0.8-15.2,5.4-18.6,14.2C28.9,45.2,27.2,45.9,25.9,45.9z M16.7,42.2C16.7,42.2,16.7,42.2,16.7,42.2l9.2,0  c0.1,0,0.3-0.1,0.6-0.6c3.9-10,11.3-15.6,21.7-16.4c8.4-0.7,15.7,2.6,21.5,9.7c0.6,0.7,0.5,1.8-0.1,2.5l-4.9,4.9l18.7,0V23.3  l-4.7,4.6c-0.4,0.3-0.9,0.5-1.3,0.5c-0.5,0-1-0.2-1.3-0.6c-11.1-11.6-24-14.9-38.1-9.8C26.9,22,19.8,30.2,16.7,42.2z M49.4,87.7  c-9.7,0-18.7-4-26.9-12l-5,4.8c-0.4,0.3-1.3,1.1-2.4,1.1l0,0c-0.9,0-2.4-0.6-2.4-2.8V57.1c0-1.6,1.1-2.9,2.8-3.2c0.1,0,0.3,0,0.4,0  h21.5c0.1,0,0.1,0,0.2,0c0.5,0.1,2.1,0.3,2.6,1.8c0.2,0.6,0.4,1.7-0.8,2.9l-5.3,5.4c4.8,5.2,10.6,7.6,17.2,7.1  c9.1-0.8,15.2-5.4,18.6-14.2c0,0,0-0.1,0.1-0.1c0.9-2.1,2.7-2.8,3.9-2.8l9.3,0c0.4,0,2.1,0.1,3.1,1.5c0.4,0.6,0.9,1.6,0.5,3  c-3.4,13.4-11.3,22.4-23.6,26.9C58.6,86.9,53.9,87.7,49.4,87.7z M22.6,71.3C22.6,71.3,22.6,71.3,22.6,71.3c0.5,0,1,0.2,1.3,0.6  c11.1,11.6,24,14.9,38.1,9.8c11-4,18.2-12.1,21.3-24.2c0,0,0,0,0,0l-9.2,0c0,0-0.3,0.1-0.5,0.6c0,0,0,0,0,0  c-4,10-11.3,15.5-21.7,16.4c-8.4,0.7-15.7-2.6-21.5-9.7c-0.6-0.7-0.5-1.8,0.1-2.5l4.9-4.9l-18.7,0v18.9l4.7-4.6  C21.7,71.5,22.1,71.3,22.6,71.3z"></path></svg>
+        </div>
         <script>
+            function audio_end(event){
+                p = event.target.parentElement;
+                if (!event.target.loop){
+                    p.children[1].innerHTML='<svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 90 90" enable-background="new 0 0 90 90" xml:space="preserve"><path d="M45,6.421c21.273,0,38.579,17.306,38.579,38.579S66.273,83.578,45,83.578c-21.273,0-38.579-17.306-38.579-38.579  S23.727,6.421,45,6.421 M45,0C20.148,0,0,20.146,0,44.999s20.148,44.999,45,44.999c24.852,0,45-20.146,45-44.999S69.852,0,45,0L45,0  z M65.5,44.999l-31.5-18v36L65.5,44.999z"></path></svg>';
+                }
+            }
             function setup_audio_metadata(event) {
                 audio = event.target;
                 var seek = audio.parentElement.children[2];
@@ -47,6 +89,12 @@
             function toggle_loop_audio(event) {
                 audio = event.target.parentElement.children[0];
                 audio.loop = !audio.loop;
+                if (audio.loop){
+                    event.target.children[0].classList.add("spin");
+                }
+                else{
+                    event.target.children[0].classList.remove("spin");
+                }
             }
             function update_audio_time(event) {
                 audio = event.target.parentElement.children[0];
@@ -54,17 +102,16 @@
             }
             function toggle_play_audio(event) {
                 el = event.target;
-                audio = event.target.parentElement.children[0];
+                audio = el.parentElement.children[0];
                 speed = el.parentElement.children[3].value;
                 audio.playbackRate = speed;
-
                 if (audio.paused) {
                     audio.play();
-                    el.innerHTML = "Pause";
+                    el.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve"><g><path d="M39.75,5.5C20.834,5.5,5.5,20.834,5.5,39.75C5.5,58.666,20.834,74,39.75,74C58.666,74,74,58.666,74,39.75   C74,20.834,58.666,5.5,39.75,5.5z M39.75,70C23.043,70,9.5,56.457,9.5,39.75C9.5,23.043,23.043,9.5,39.75,9.5   C56.457,9.5,70,23.043,70,39.75C70,56.457,56.457,70,39.75,70z"></path><path d="M37.125,52.375c0,2.348-1.903,4.25-4.25,4.25l0,0c-2.347,0-4.25-1.902-4.25-4.25V28.75c0-2.347,1.903-4.25,4.25-4.25l0,0   c2.347,0,4.25,1.903,4.25,4.25V52.375z"></path><path d="M51.125,52.375c0,2.348-1.902,4.25-4.25,4.25l0,0c-2.348,0-4.25-1.902-4.25-4.25V28.75c0-2.347,1.902-4.25,4.25-4.25l0,0   c2.348,0,4.25,1.903,4.25,4.25V52.375z"></path></g></svg>';
                 }
                 else {
                     audio.pause();
-                    el.innerHTML = "Play"
+                    el.innerHTML = '<svg class="icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 90 90" enable-background="new 0 0 90 90" xml:space="preserve"><path d="M45,6.421c21.273,0,38.579,17.306,38.579,38.579S66.273,83.578,45,83.578c-21.273,0-38.579-17.306-38.579-38.579  S23.727,6.421,45,6.421 M45,0C20.148,0,0,20.146,0,44.999s20.148,44.999,45,44.999c24.852,0,45-20.146,45-44.999S69.852,0,45,0L45,0  z M65.5,44.999l-31.5-18v36L65.5,44.999z"></path></svg>';
                 }
             }
             function update_audio_speed(event) {
diff --git a/layouts/shortcodes/video.html b/layouts/shortcodes/video.html
index a9aea63..8e2b01d 100644
--- a/layouts/shortcodes/video.html
+++ b/layouts/shortcodes/video.html
@@ -1,31 +1,86 @@
 <style>
-    .video-player{
+    .video-player {
         display: flex;
         flex-direction: column;
         align-items: center;
     }
-    .media-container{
-        width:fit-content;
+
+    .video-controls {
+        display: flex;
+        flex-direction: row;
+        width: 100%;
+        height: fit-content;
+    }
+
+    .video-controls p {
+        width: min-content;
+    }
+
+    .media-seek {
+        width: 100%;
+    }
+
+    .video-controls>* {
+        margin: 5px;
+    }
+
+    .video-controls select,
+    .video-controls button {
+        background-color: transparent;
+        border-color: var(--theme-accent);
+        color: var(--theme-accent);
+        border-radius: 3px;
+        padding: 0.5rem;
+    }
+
+    .icon svg {
+        width: 2.25rem;
+        height: fit-content;
+        z-index: -1;
+        background-color: transparent;
+        pointer-events: none;
+    }
+
+    .icon path,
+    .icon rect {
+        stroke: var(--theme-accent);
+        fill: var(--theme-accent);
+    }
+
+    .icon svg circle,
+    .icon svg>rect {
+        stroke: var(--theme-accent);
+        fill: transparent;
+        stroke-width: 6;
+    }
+    .video-player:fullscreen{
+        height:100vh;
+        width:100vw;
+    }
+    .video-player:fullscreen video{
+        max-height: 100vh;
+        height:100%;
+        max-width: 100vw;
+        width: 100vw;
     }
-.video-controls{
-    display:flex;
-    flex-direction: row;
-    width:100%;
-}
-.video-controls p{
-    width:min-content;
-}
-.media-seek{
-    width:100%;
-}
 </style>
 <div class="media-container">
     <div class="video-player">
-        <video preload="metadata" onclick="playthis(event)" onloadedmetadata="setup_video_metadata(event)" ontimeupdate="setup_video_metadata(event)">
+        <video preload="metadata" onclick="playthis(event)" onloadedmetadata="setup_video_metadata(event)"
+            ontimeupdate="setup_video_metadata(event)">
             <source src='{{.Site.BaseURL}}{{.Get "src" }}'>
         </video>
         <div class="video-controls">
-            <button onclick="toggle_video_play(event)">Play</button>
+            <div onclick="toggle_video_play(event)" class="icon">
+                <svg width="120" height="120" viewBox="0 0 120 120">
+                    <path style="opacity:0.99;fill-opacity:1;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1"
+                        d="m 36.961917,29.902848 c 3.596357,-1.826163 63.333473,26.918008 63.449063,32.530093 0.1386,6.729203 -61.229407,35.615675 -63.254766,33.796117 -1.971501,-1.557746 -3.672784,-64.52183 -0.194297,-66.32621 z"
+                        id="path1060" sodipodi:nodetypes="cscc" />
+                    <circle style="opacity:0.99;fill-opacity:0;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1"
+                        id="path2040" cx="60.062084" cy="62.077591" r="52.403164" />
+                </svg>
+            </div>
+            </button>
             <input class="media-seek" type="range" onchange="update_video_time(event)" value="0">
             <select onchange="update_video_speed(event)">
                 <option value="1" selected>1x</option>
@@ -35,90 +90,131 @@
                 <option value="3">3x</option>
             </select>
             <p><span class="audio-currentTime"></span><span class="audio-duration"></span></p>
+            <div class="icon" onclick="fullscreen(event)">
+                <svg width="120" height="120" viewBox="0 0 120 120">
+                    <path
+                        style="opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+                        d="M 46.964564,56.005523 29.64354,38.443145 15.744327,51.812481 15.624368,16.779513 l 36.623948,0.03226 -13.177737,14.17536 16.622539,16.392689 z"
+                        id="path8948-3"/>
+                    <path
+                        style="opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+                        d="M 55.129887,73.388205 38.422614,90.210417 51.067135,104.89922 16.395468,104.33333 16.434945,67.605641 30.111493,81.28219 46.504182,64.659651 Z"
+                        id="path8948-3-5"/>
+                    <path
+                        style="opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+                        d="M 63.363444,46.935211 80.997081,30.825588 67.627745,17.036604 102.68744,17.447746 102.62846,52.646518 88.168059,39.041226 71.989147,55.663767 Z"
+                        id="path8948-3-6"/>
+                    <path
+                        style="opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+                        d="M 71.956318,65.743071 91.343851,82.735377 104.06395,70.648701 103.79532,105.13832 69.166628,105.79193 82.579575,93.184265 63.227764,74.368773 Z"
+                        id="path8948-3-5-2"/>
+                </svg>
+
+            </div>
+
         </div>
-        <script>
-            function setup_video_metadata(event){
-                video = event.target;
-                var seek = video.parentElement.children[1].children[1];
-                seek.min = 0;
-                seek.max = video.duration;
-                seek.value = video.currentTime;
-                details = video.parentElement.children[1].children[3].children;
-                details[0].innerHTML = timeToText(video.currentTime)+"/";
-                details[1].innerHTML = timeToText(video.duration);
-
-            }
-            function playthis(event){
-                if (event.target.paused){
-                    event.target.playbackRate = video.parentElement.children[1].children[2].value;
-                    event.target.play();
-                    video.parentElement.children[1].children[0].innerHTML="Pause";
-                }
-                else{
-                    event.target.pause();
-                    video.parentElement.children[1].children[0].innerHTML="Play";
-                }
-            }
-            function toggle_video_play(event){
-                video = event.target.parentElement.parentElement.children[0];
-                if (video.paused){
-                    video.playbackRate = video.parentElement.children[1].children[2].value;
-                    video.play();
-                    video.parentElement.children[1].children[0].innerHTML="Pause";
-                }
-                else{
-                    video.pause();
-                    video.parentElement.children[1].children[0].innerHTML="Play";
-                }
-            }
-            function update_video_speed(event){
-                video = event.target.parentElement.parentElement.children[0];
-                video.playbackRate=event.target.value;
-            }
-            function update_video_time(event){
-                video = event.target.parentElement.parentElement.children[0];
-                video.currentTime = event.target.value;
-            }
-            
-            function timeToText(t) {
-                hours = 0;
-                minutes = 0;
-                seconds = 0;
-                if (t > 60 * 60) {
-                    hours = Math.floor(t / 60 / 60);
-                    t = t - hours * 60 * 60;
-                }
-                if (t > 60) {
-                    minutes = Math.floor(t / 60);
-                    t = t - minutes * 60
+            <script>
+                function setup_video_metadata(event) {
+                    video = event.target;
+                    var seek = video.parentElement.children[1].children[1];
+                    seek.min = 0;
+                    seek.max = video.duration;
+                    seek.value = video.currentTime;
+                    details = video.parentElement.children[1].children[3].children;
+                    details[0].innerHTML = timeToText(video.currentTime) + "/";
+                    details[1].innerHTML = timeToText(video.duration);
 
                 }
-                if (t > 1) {
-                    seconds = Math.floor(t);
-                }
-                text = "";
-                if (hours > 0) {
-                    text += hours + ":";
-                }
-                if (minutes > 0 || hours > 0) {
-                    if (minutes == 0) {
-                        minutes = "00"
+                function playthis(event) {
+                    if (event.target.paused) {
+                        event.target.playbackRate = video.parentElement.children[1].children[2].value;
+                        event.target.play();
+                        var icon = "<svg width = \"120\" height = \"120\" viewBox = \"0 0 120 120\" > <g id=\"layer1\" > <circle  =\"opacity:0.99;fill-opacity:0;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1\" id =\"path2040\" cx =\"60.062084\" cy =\"62.077591\" r =\"52.403164\" /> <rect style =\"opacity:0.99;fill-opacity:1;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" id =\"rect2858\" width =\"13.503889\" height =\"74.311569\" x =\"37.891518\" y =\"25.657549\" /> <rect style =\"opacity:0.99;fill-opacity:1;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" id =\"rect2858-3\" width =\"13.503889\" height =\"74.311569\" x =\"67.821785\" y =\"25.526461\" /> </g > </svg>"
+                        video.parentElement.children[1].children[0].innerHTML = icon;
                     }
-                    if (minutes < 10) {
-                        text += "0"
+                    else {
+                        event.target.pause();
+                        var icon = "<svg width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><path style=\"opacity:0.99;fill-opacity:1;stroke-width:4;stroke-dasharray:none;stroke-opacity:1\"d=\"m 36.961917,29.902848 c 3.596357,-1.826163 63.333473,26.918008 63.449063,32.530093 0.1386,6.729203 -61.229407,35.615675 -63.254766,33.796117 -1.971501,-1.557746 -3.672784,-64.52183 -0.194297,-66.32621 z\" id=\"path1060\" sodipodi:nodetypes=\"cscc\" />          <circle style=\"opacity:0.99;fill-opacity:0;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1\" id=\"path2040\" cx=\"60.062084\" cy=\"62.077591\" r=\"52.403164\" /></svg>";
+                        video.parentElement.children[1].children[0].innerHTML = icon;
                     }
-                    text += minutes + ":"
                 }
-                if (seconds == 0 && (minutes > 0 || hours > 0)) {
-                    seconds = "00";
+                function fullscreen(event) {
+                    video = event.target.parentElement.parentElement;
+                    if (document.fullscreenElement) {
+                        document.exitFullscreen();
+                        var icon = "<svg width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"> <path     style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 46.964564,56.005523 29.64354,38.443145 15.744327,51.812481 15.624368,16.779513 l 36.623948,0.03226 -13.177737,14.17536 16.622539,16.392689 z\" id=\"path8948-3\" sodipodi:nodetypes=\"cccccccc\" /> <path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 55.129887,73.388205 38.422614,90.210417 51.067135,104.89922 16.395468,104.33333 16.434945,67.605641 30.111493,81.28219 46.504182,64.659651 Z\" id=\"path8948-3-5\" sodipodi:nodetypes=\"cccccccc\" /> <path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\"     d=\"M 63.363444,46.935211 80.997081,30.825588 67.627745,17.036604 102.68744,17.447746 102.62846,52.646518 88.168059,39.041226 71.989147,55.663767 Z\" id=\"path8948-3-6\" sodipodi:nodetypes=\"cccccccc\" /> <path    style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 71.956318,65.743071 91.343851,82.735377 104.06395,70.648701 103.79532,105.13832 69.166628,105.79193 82.579575,93.184265 63.227764,74.368773 Z\" id=\"path8948-3-5-2\" sodipodi:nodetypes=\"cccccccc\" /></svg>";
+                        event.target.innerHTML = icon;
+                    }
+                    else {
+                        video.requestFullscreen();
+                        var icon = "<svg width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"> <path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 24.352868,16.779459 41.673892,34.341837 55.573105,20.972501 55.693064,56.005469 19.069116,55.973209 32.246853,41.797849 15.624314,25.40516 Z\" id=\"path8948-3\"/><path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 16.395415,96.170716 33.102688,79.348504 20.458167,64.659701 55.129834,65.225591 55.090357,101.95328 41.413809,88.276731 25.02112,104.89927 Z\" id=\"path8948-3-5\"/> <path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 102.6875,25.765108 85.05386,41.874731 97.415443,56.469918 63.061175,56.361101 63.422481,20.053801 77.882882,33.659093 94.061794,17.036552 Z\" id=\"path8948-3-6\" /> <path style=\"opacity:0.99;fill-opacity:1;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" d=\"M 95.335449,105.79197 76.351017,88.674877 64.23557,102.19642 63.496447,66.396722 98.32669,66.448539 85.921496,80.567834 104.064,97.166269 Z\" id=\"path8948-3-5-2\" /></svg>";
+                        event.target.innerHTML = icon;
+                    }
+
+
                 }
-                if (seconds < 10) {
-                    text += "0";
+                function toggle_video_play(event) {
+                    video = event.target.parentElement.parentElement.children[0];
+                    if (video.paused) {
+                        video.playbackRate = video.parentElement.children[1].children[2].value;
+                        video.play();
+                        var icon = "<svg width = \"120\" height = \"120\" viewBox = \"0 0 120 120\" > <g id=\"layer1\" > <circle  =\"opacity:0.99;fill=fill-opacity:0;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1\" id =\"path2040\" cx =\"60.062084\" cy =\"62.077591\" r =\"52.403164\" /> <rect style =\"opacity:0.99;fill-opacity:1;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" id =\"rect2858\" width =\"13.503889\" height =\"74.311569\" x =\"37.891518\" y =\"25.657549\" /> <rect style =\"opacity:0.99;fill-opacity:1;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1\" id =\"rect2858-3\" width =\"13.503889\" height =\"74.311569\" x =\"67.821785\" y =\"25.526461\" /> </g > </svg>";
+                        video.parentElement.children[1].children[0].innerHTML = icon;
+                    }
+                    else {
+                        video.pause();
+                        var icon = "<svg width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><path style=\"opacity:0.99;fill-opacity:1;stroke-width:4;stroke-dasharray:none;stroke-opacity:1\"d=\"m 36.961917,29.902848 c 3.596357,-1.826163 63.333473,26.918008 63.449063,32.530093 0.1386,6.729203 -61.229407,35.615675 -63.254766,33.796117 -1.971501,-1.557746 -3.672784,-64.52183 -0.194297,-66.32621 z\" id=\"path1060\" sodipodi:nodetypes=\"cscc\" />          <circle style=\"opacity:0.99;fill-opacity:0;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1\" id=\"path2040\" cx=\"60.062084\" cy=\"62.077591\" r=\"52.403164\" /></svg>";
+                        video.parentElement.children[1].children[0].innerHTML = icon;
+                    }
                 }
-                text += seconds
-                return text;
-            }
-        </script>
+                function update_video_speed(event) {
+                    video = event.target.parentElement.parentElement.children[0];
+                    video.playbackRate = event.target.value;
+                }
+                function update_video_time(event) {
+                    video = event.target.parentElement.parentElement.children[0];
+                    video.currentTime = event.target.value;
+                }
+
+                function timeToText(t) {
+                    hours = 0;
+                    minutes = 0;
+                    seconds = 0;
+                    if (t > 60 * 60) {
+                        hours = Math.floor(t / 60 / 60);
+                        t = t - hours * 60 * 60;
+                    }
+                    if (t > 60) {
+                        minutes = Math.floor(t / 60);
+                        t = t - minutes * 60
+
+                    }
+                    if (t > 1) {
+                        seconds = Math.floor(t);
+                    }
+                    text = "";
+                    if (hours > 0) {
+                        text += hours + ":";
+                    }
+                    if (minutes > 0 || hours > 0) {
+                        if (minutes == 0) {
+                            minutes = "00"
+                        }
+                        if (minutes < 10) {
+                            text += "0"
+                        }
+                        text += minutes + ":"
+                    }
+                    if (seconds == 0 && (minutes > 0 || hours > 0)) {
+                        seconds = "00";
+                    }
+                    if (seconds < 10) {
+                        text += "0";
+                    }
+                    text += seconds
+                    return text;
+                }
+            </script>
     </div>
     <noscript>
         <style>
@@ -130,8 +226,7 @@
             <source src='{{.Site.BaseURL}}{{.Get "src" }}'>
         </video>
     </noscript>
-    <p class="caption">
-        {{.Get "caption"}} {{if .Get "source"}}<a href='{{.Get "source"}}'>Source</a>{{end}}
 
+    <p class="caption">{{.Get "caption"}} {{if .Get "source"}}<a href='{{.Get "source"}}'>Source</a>{{end}}
     </p>
 </div>
\ No newline at end of file
diff --git a/layouts/shortcodes/yesterweb.html b/layouts/shortcodes/yesterweb.html
deleted file mode 100644
index fd90118..0000000
--- a/layouts/shortcodes/yesterweb.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<a href="https://webring.yesterweb.org/noJS/index.php?d=prev&url=https://yesterweb.org/">Previous</a>
-                        <a href="https://webring.yesterweb.org/noJS/index.php?d=rand&url=https://yesterweb.org/">Random</a>
-                        <a href="https://webring.yesterweb.org/noJS/index.php?d=next&url=https://yesterweb.org/">Next</a>
\ No newline at end of file
diff --git a/static/css/theme.css b/static/css/theme.css
index 5a45443..a8f4152 100644
--- a/static/css/theme.css
+++ b/static/css/theme.css
@@ -181,7 +181,7 @@ blockquote {
 }
 .gallery>*{
     margin:0.1rem;
-    border:1px solid var(--theme-color-accent);
+    border:1px solid var(--theme-accent);
 }
 .gallery p{
     width:100%;
diff --git a/static/res/expand.svg b/static/res/expand.svg
new file mode 100644
index 0000000..38c0e76
--- /dev/null
+++ b/static/res/expand.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="120"
+   height="120"
+   viewBox="0 0 120 120"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+   sodipodi:docname="expand.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:zoom="7.0166667"
+     inkscape:cx="46.247031"
+     inkscape:cy="55.154394"
+     inkscape:window-width="1920"
+     inkscape:window-height="989"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1"
+     showguides="false" />
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:0.99;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       id="rect7492"
+       width="98.961357"
+       height="98.961357"
+       x="10.682183"
+       y="10.682183" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 46.964564,56.005523 29.64354,38.443145 15.744327,51.812481 15.624368,16.779513 l 36.623948,0.03226 -13.177737,14.17536 16.622539,16.392689 z"
+       id="path8948-3"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 55.129887,73.388205 38.422614,90.210417 51.067135,104.89922 16.395468,104.33333 16.434945,67.605641 30.111493,81.28219 46.504182,64.659651 Z"
+       id="path8948-3-5"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 63.363444,46.935211 80.997081,30.825588 67.627745,17.036604 102.68744,17.447746 102.62846,52.646518 88.168059,39.041226 71.989147,55.663767 Z"
+       id="path8948-3-6"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 71.956318,65.743071 91.343851,82.735377 104.06395,70.648701 103.79532,105.13832 69.166628,105.79193 82.579575,93.184265 63.227764,74.368773 Z"
+       id="path8948-3-5-2"
+       sodipodi:nodetypes="cccccccc" />
+  </g>
+</svg>
diff --git a/static/res/loop.svg b/static/res/loop.svg
new file mode 100644
index 0000000..868f910
--- /dev/null
+++ b/static/res/loop.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="120"
+   height="120"
+   viewBox="0 0 120 120"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+   sodipodi:docname="loop.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:zoom="4.9615326"
+     inkscape:cx="41.821755"
+     inkscape:cy="53.612467"
+     inkscape:window-width="1920"
+     inkscape:window-height="989"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1"
+     showguides="false" />
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <circle
+       style="opacity:0.99;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2040"
+       cx="60.062084"
+       cy="62.077591"
+       r="52.403164" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.1;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 49.086093,104.69797 53.85938,96.982017 C -0.70319734,64.562086 46.019709,40.176232 48.130402,38.442953 c 0,0 4.487934,4.354976 5.546329,5.309403 1.84557,1.664276 5.129158,-20.199369 5.129158,-20.199369 l -22.368136,0.483004 5.548034,5.713299 c 0,0 -56.905236,37.386495 7.100306,74.94868 z"
+       id="path4435"
+       sodipodi:nodetypes="cccscccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.1;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="m 72.493272,21.303543 -4.773287,7.715948 c 54.562575,32.419931 7.839671,56.805785 5.728978,58.539064 0,0 -4.487934,-4.354976 -5.546329,-5.309403 -1.845568,-1.664276 -5.129158,20.199368 -5.129158,20.199368 l 22.368136,-0.483 -5.548034,-5.713302 c 0,0 56.905242,-37.386495 -7.100306,-74.948675 z"
+       id="path4435-7"
+       sodipodi:nodetypes="cccscccc" />
+  </g>
+</svg>
diff --git a/static/res/pause.svg b/static/res/pause.svg
new file mode 100644
index 0000000..ee03ece
--- /dev/null
+++ b/static/res/pause.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="120"
+   height="120"
+   viewBox="0 0 120 120"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+   sodipodi:docname="pause.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:zoom="2.4807663"
+     inkscape:cx="-61.876042"
+     inkscape:cy="23.782974"
+     inkscape:window-width="1920"
+     inkscape:window-height="989"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <circle
+       style="opacity:0.99;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2040"
+       cx="60.062084"
+       cy="62.077591"
+       r="52.403164" />
+    <rect
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2858"
+       width="13.503889"
+       height="74.311569"
+       x="37.891518"
+       y="25.657549" />
+    <rect
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:3.2;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2858-3"
+       width="13.503889"
+       height="74.311569"
+       x="67.821785"
+       y="25.526461" />
+  </g>
+</svg>
diff --git a/static/res/play.svg b/static/res/play.svg
new file mode 100644
index 0000000..fea6a17
--- /dev/null
+++ b/static/res/play.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="120"
+   height="120"
+   viewBox="0 0 120 120"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+   sodipodi:docname="play.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:zoom="4.9615326"
+     inkscape:cx="47.062071"
+     inkscape:cy="61.674492"
+     inkscape:window-width="1920"
+     inkscape:window-height="989"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 36.961917,29.902848 c 3.596357,-1.826163 63.333473,26.918008 63.449063,32.530093 0.1386,6.729203 -61.229407,35.615675 -63.254766,33.796117 -1.971501,-1.557746 -3.672784,-64.52183 -0.194297,-66.32621 z"
+       id="path1060"
+       sodipodi:nodetypes="cscc" />
+    <circle
+       style="opacity:0.99;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:6.4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2040"
+       cx="60.062084"
+       cy="62.077591"
+       r="52.403164" />
+  </g>
+</svg>
diff --git a/static/res/shrink.svg b/static/res/shrink.svg
new file mode 100644
index 0000000..3d60618
--- /dev/null
+++ b/static/res/shrink.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="120"
+   height="120"
+   viewBox="0 0 120 120"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+   sodipodi:docname="shrink.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:zoom="4.9615326"
+     inkscape:cx="49.077578"
+     inkscape:cy="76.790789"
+     inkscape:window-width="1920"
+     inkscape:window-height="989"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1"
+     showguides="false" />
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:0.99;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       id="rect7492"
+       width="98.961357"
+       height="98.961357"
+       x="10.682183"
+       y="10.682183" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 24.352868,16.779459 41.673892,34.341837 55.573105,20.972501 55.693064,56.005469 19.069116,55.973209 32.246853,41.797849 15.624314,25.40516 Z"
+       id="path8948-3"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 16.395415,96.170716 33.102688,79.348504 20.458167,64.659701 55.129834,65.225591 55.090357,101.95328 41.413809,88.276731 25.02112,104.89927 Z"
+       id="path8948-3-5"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 102.6875,25.765108 85.05386,41.874731 97.415443,56.469918 63.061175,56.361101 63.422481,20.053801 77.882882,33.659093 94.061794,17.036552 Z"
+       id="path8948-3-6"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="opacity:0.99;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.58928;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+       d="M 95.335449,105.79197 76.351017,88.674877 64.23557,102.19642 63.496447,66.396722 98.32669,66.448539 85.921496,80.567834 104.064,97.166269 Z"
+       id="path8948-3-5-2"
+       sodipodi:nodetypes="cccccccc" />
+  </g>
+</svg>