summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2022-06-11 13:59:33 +0530
committerAndinus <andinus@nand.sh>2022-06-11 14:03:34 +0530
commitf156f380d4de118e31036e80144154bdcb664ed6 (patch)
tree5373a1aff0699774aafa7979c4c5584669187eb1
parent89c60aee5a602ed5bfd73a9d5bcbbf9945aac44f (diff)
downloadcrater-f156f380d4de118e31036e80144154bdcb664ed6.tar.gz
Display gallery title, fix authentication, show directories
- Earlier non-authenticated users could access the images too.
- Serve original image if thumbnail doesn't exist.
- Show directories in gallery.
- Remove lazy loading attribute.
-rw-r--r--lib/Crater/Gallery.rakumod51
-rw-r--r--lib/Crater/Routes/Auth.rakumod1
-rw-r--r--lib/Crater/Routes/Gallery.rakumod15
-rw-r--r--resources/css/style.css32
-rw-r--r--resources/js/gallery.js2
-rw-r--r--templates/gallery.crotmp8
6 files changed, 77 insertions, 32 deletions
diff --git a/lib/Crater/Gallery.rakumod b/lib/Crater/Gallery.rakumod
index 19b0d69..448593f 100644
--- a/lib/Crater/Gallery.rakumod
+++ b/lib/Crater/Gallery.rakumod
@@ -1,25 +1,46 @@
 class Crater::Gallery {
     has IO $.directory is required;
+    has Str $!title;
+
+    submethod TWEAK() {
+        my $title-file = $!directory.add(".crater/title");
+        $!title = $title-file.slurp.chomp if $title-file.f;
+    }
+
+    #| Accessor for $!title.
+    method title() { $!title }
 
     method list() {
         my @gallery;
-        for $!directory.dir.sort(*.modified) {
-            if .IO.d {
+        my @paths = $!directory.dir;
+
+        with $!title {
+            push @gallery, %( :type<heading>, :text($_) );
+        }
+
+        # Add directories on top.
+        for @paths.grep(*.d) {
+            push @gallery, %( :type<directory>,
+                              :text($_.relative($!directory)) );
+        }
 
-            } elsif .IO.f {
-                my Str $ext = .extension.lc;
-                if $ext eq "jpg"|"png" {
-                    push @gallery, %(
-                        :type<img>, :src($_.relative($!directory)),
-                        :alt($_)
-                    );
-                } elsif $ext eq "0" {
-                    push @gallery, %( :type<heading>, :text($_.slurp) );
-                } elsif $ext eq "txt" {
-                    push @gallery, %( :type<text>, :text($_.slurp) );
-                } else {
-                    warn "Unhandled file :$_";
+        for @paths.grep(*.f).sort(*.modified) {
+            my Str $ext = .extension.lc;
+            # For images get the original if thumbnail doesn't exist,
+            # otherwise use the thumbnail.
+            if $ext eq "jpg"|"png" {
+                my $rel = $_.relative($!directory);
+                my $alt = $rel;
+                unless $!directory.add(".crater/thumbnails").add($rel).f {
+                    $rel ~= "?original";
                 }
+                push @gallery, %( :type<img>, :src($rel), :$alt );
+            } elsif $ext eq "0" {
+                push @gallery, %( :type<heading>, :text($_.slurp.chomp) );
+            } elsif $ext eq "txt" {
+                push @gallery, %( :type<text>, :text($_.slurp.chomp) );
+            } else {
+                note "Unhandled file: $_";
             }
         }
         return @gallery;
diff --git a/lib/Crater/Routes/Auth.rakumod b/lib/Crater/Routes/Auth.rakumod
index 23872e9..73e6dc7 100644
--- a/lib/Crater/Routes/Auth.rakumod
+++ b/lib/Crater/Routes/Auth.rakumod
@@ -13,7 +13,6 @@ sub auth-routes(
         get -> Crater::Session $session, 'login' {
             template 'login.crotmp', { :!error };
         }
-
         post -> Crater::Session $session, 'login' {
             request-body -> (:$pass!, *%) {
                 if $password eq $pass {
diff --git a/lib/Crater/Routes/Gallery.rakumod b/lib/Crater/Routes/Gallery.rakumod
index cf79cc6..aa3e4b6 100644
--- a/lib/Crater/Routes/Gallery.rakumod
+++ b/lib/Crater/Routes/Gallery.rakumod
@@ -8,6 +8,15 @@ sub gallery-routes(
     Crater::Gallery :$gallery!, #= gallery object
 ) is export {
     route {
+        # Logged in users can view images.
+        get -> LoggedIn $session, 'resources', 'img', *@path, :$original {
+            my $dir = $gallery.directory;
+            # Serve the thumbnail unless original image was requested.
+            $dir .= add(".crater/thumbnails") unless $original.defined;
+            static $dir, @path;
+        }
+
+        # Gallery view.
         get -> LoggedIn $session {
             template 'gallery.crotmp', {
                 gallery => $gallery.list(),
@@ -15,11 +24,9 @@ sub gallery-routes(
             };
         }
 
-        get -> {
-            redirect '/login', :see-other;
-        }
+        # Redirect to login page if not logged in.
         get -> *@path {
-            static $gallery.directory.add(".crater/thumbnails"), @path;
+            redirect '/login', :see-other;
         }
     }
 }
diff --git a/resources/css/style.css b/resources/css/style.css
index 76af98e..cc2cb3a 100644
--- a/resources/css/style.css
+++ b/resources/css/style.css
@@ -56,21 +56,20 @@ img {
     min-width: 30%;
 }
 
-img, .text { width: 400px; }
-.heading { width: 380px; }
+img { width: 400px; }
+.heading, .text, .directory { width: 380px; }
 @media only screen and (max-width: 512px) {
-    img, .text { width: 368px; }
-    .heading { width: 350px; }
+    img { width: 368px; }
+    .heading, .text, .directory { width: 350px; }
 }
 @media only screen and (max-width: 450px) {
-    img, .text { width: 350px; }
-    .heading { width: 330px; }
+    img { width: 350px; }
+    .heading, .text, .directory { width: 330px; }
 }
 @media only screen and (max-width: 400px) {
-    img, .text { width: 330px; }
-    .heading { width: 310px; }
+    img { width: 330px; }
+    .heading, .text, .directory { width: 310px; }
 }
-
 .heading {
     box-shadow: var(--blue-intense-bg) 0px 0px 0px 2px inset,
                 var(--bg-main) 10px -10px 0px -3px,
@@ -83,7 +82,6 @@ img, .text { width: 400px; }
                 var(--red-intense-bg) 40px -40px;
     padding: 1em;
 }
-
 .text {
     box-shadow: var(--magenta-intense-bg) 0px 0px 0px 3px,
                 var(--green-subtle-bg) 0px 0px 0px 6px,
@@ -92,6 +90,20 @@ img, .text { width: 400px; }
                 var(--red-intense-bg) 0px 0px 0px 15px;
     padding: 1em;
 }
+.directory {
+    box-shadow: var(--bg-special-cold) 0px 0px 0px 3px,
+                var(--bg-special-calm) 0px 0px 0px 6px;
+    padding: 1em;
+}
+.directory:hover {
+    background-color: var(--bg-alt);
+}
+.directory:before {
+    content: '📁 ';
+}
+.directory:hover:before {
+    content: '📂 ';
+}
 
 #gallery {
     margin: auto;
diff --git a/resources/js/gallery.js b/resources/js/gallery.js
index 2a608f5..5643ce2 100644
--- a/resources/js/gallery.js
+++ b/resources/js/gallery.js
@@ -71,7 +71,7 @@ const onImagesLoaded = (container, event) => {
 
 const gallery = document.getElementById("gallery");
 const imagesLoaded = (remaining, failed, progressBar) => {
-    bricks.pack();
+    bricks.pack(); // packing images
 
     progressBar.value = 100;
     document.getElementById("loading").style.display = "none";
diff --git a/templates/gallery.crotmp b/templates/gallery.crotmp
index 6aead73..253339e 100644
--- a/templates/gallery.crotmp
+++ b/templates/gallery.crotmp
@@ -1,5 +1,8 @@
 <:use 'templates/base.crotmp'>
   <|page(.title)>
+    <noscript>
+      <div class="alert" role="alert">JavaScript required.</div>
+    </noscript>
     <div id="loading">
       <label for="loading-progress">Loading Images:</label>
       <progress id="loading-progress" max="100" value="0"></progress>
@@ -10,8 +13,11 @@
     </div>
     <div id="gallery">
       <@gallery : $i>
+        <?{ $i.<type> eq 'directory' }>
+        <div class="directory"><$i.<text>></div>
+        </?>
         <?{ $i.<type> eq 'img' }>
-        <img alt="<$i.<alt>>" src="<$i.<src>>" loading="lazy">
+        <img alt="<$i.<alt>>" src="/resources/img/<$i.<src>>">
         </?>
         <?{ $i.<type> eq 'text' }>
         <div class="text"><$i.<text>></div>