From 8f360dd9cc45bb14431238ccc5e3d137c020fa7b Mon Sep 17 00:00:00 2001
From: Kit La Touche <kit@transneptune.net>
Date: Wed, 23 Oct 2024 21:52:24 -0400
Subject: Do a big mobile app design thing

Mobile-friendly anyway. Thanks to
[Miriam](https://www.miriamsuzanne.com/) for the CSS that enables a
sliding menu on mobile size, constant menu on larger.
---
 ui/routes/(app)/+layout.svelte | 108 +++++++++++++++++++++++++++++------------
 1 file changed, 78 insertions(+), 30 deletions(-)

(limited to 'ui/routes/(app)/+layout.svelte')

diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte
index 9abaaf4..b63a607 100644
--- a/ui/routes/(app)/+layout.svelte
+++ b/ui/routes/(app)/+layout.svelte
@@ -4,7 +4,7 @@
 	import { onMount, onDestroy } from 'svelte';
 
 	import { boot, subscribeToEvents } from '$lib/apiServer';
-	import { currentUser, logins, channelsList, messages } from '$lib/store';
+	import { showMenu, currentUser, logins, channelsList, messages } from '$lib/store';
 
     import ChannelList from '$lib/components/ChannelList.svelte';
     import CreateChannelForm from '$lib/components/CreateChannelForm.svelte';
@@ -12,6 +12,15 @@
 
     let loading = true;
     let events = null;
+    let showMenuValue;
+    showMenu.subscribe((value) => {
+        showMenuValue = value;
+    });
+
+
+    function toggleMenu() {
+        showMenu.update((value) => !value);
+    }
 
     $: channel = $page?.params?.channel;
 
@@ -57,37 +66,76 @@
 {#if loading}
     <h2>Loading&hellip;</h2>
 {:else}
-    <div id="interface">
-        <div class="channel-list">
-            <ChannelList active={channel} />
-        </div>
-        <div class="active-channel">
-            <slot />
-        </div>
-        <div class="create-channel">
-            <CreateChannelForm />
-        </div>
-        <div class="create-message">
-            <MessageInput {channel} />
-        </div>
+    <div id="interface" class="h-full pt-20 p-2">
+        <main>
+            <div class="active-channel border border-solid border-gray-400 rounded-[1.25rem]">
+                <slot />
+            </div>
+            <div class="create-message overflow-scroll max-h-full">
+                <MessageInput {channel} />
+            </div>
+        </main>
+
+        <nav id="sidebar" data-expanded={showMenuValue}>
+            <button class="h-4 w-4" aria-controls="sidebar" aria-expanded={showMenuValue} on:click={toggleMenu}>&#10006;</button>
+            <div class="channel-list">
+                <ChannelList active={channel} />
+            </div>
+            <div class="create-channel">
+                <CreateChannelForm />
+            </div>
+        </nav>
     </div>
 {/if}
 
 <style>
-    #interface {
-        height: 88vh;
-        margin: 1rem;
-        display: grid;
-        grid-template-columns: 18rem auto;
-        grid-template-rows: auto 2rem;
-        grid-gap: 0.25rem;
-    }
-    #interface div {
-        max-height: 100%;
-        overflow: scroll;
-    }
-    #interface .active-channel {
-        border: 1px solid grey;
-        border-radius: 1.25rem;
-    }
+#interface {
+  margin: unset;
+  min-block-size: 100%;
+  display: grid;
+  grid-template: 
+    'side main' 1fr
+    / auto 1fr
+  ;
+  
+  @media (width > 50em) {
+    --toggle-display: none;
+    --overlay: static;
+    --translate: 0;
+  }
+}
+nav {
+    grid-area: side;
+    background-color: rgb(var(--color-surface-600));
+    inset: 0 auto 0 0;
+    padding: 0.25rem;
+    position: var(--overlay, absolute);
+    transition: translate 300ms ease-out;
+    height: 100vh;
+    width: 21rem;
+}
+nav button {
+    position: absolute;
+    top: 0;
+    right: 0;
+}
+.active-channel {
+    height: 87vh;
+    overflow: scroll;
+}
+.channel-list {
+    height: 94vh;
+    overflow: scroll;
+}
+main {
+    grid-area: main;
+    max-height: 88vh;  /* How do we ensure that this is 100vh - header size? */
+}
+nav[data-expanded=false] {
+  translate: var(--translate, -100% 0);
+}
+[aria-controls="sidebar"] {
+  display: var(--toggle-display, revert);
+}
+
 </style>
-- 
cgit v1.2.3

