From 433d8b3bcc15d58d9c78127c239fb98fefadab59 Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Sun, 10 Dec 2023 19:16:34 +0800
Subject: [PATCH] Adjustments to welcome and login pages

---
 src/index.css         |  9 ++++
 src/pages/login.css   |  2 +-
 src/pages/login.jsx   | 77 ++++++++++++++++++++++++----------
 src/pages/welcome.css | 87 +++++++++++++++-----------------------
 src/pages/welcome.jsx | 98 ++++++++++++++++++++++---------------------
 5 files changed, 148 insertions(+), 125 deletions(-)

diff --git a/src/index.css b/src/index.css
index b6cdb5cd..8fcbe497 100644
--- a/src/index.css
+++ b/src/index.css
@@ -242,6 +242,15 @@ button,
 :is(button, .button).plain4:not(:disabled, .disabled):is(:hover, :focus) {
   color: var(--text-color);
 }
+:is(button, .button).plain5 {
+  background-color: transparent;
+  color: var(--link-color);
+  text-decoration: underline;
+  text-decoration-color: var(--link-faded-color);
+}
+:is(button, .button).plain5:not(:disabled, .disabled):is(:hover, :focus) {
+  text-decoration: underline;
+}
 :is(button, .button).light {
   background-color: var(--bg-faded-color);
   color: var(--text-color);
diff --git a/src/pages/login.css b/src/pages/login.css
index 16873c3b..d142f67a 100644
--- a/src/pages/login.css
+++ b/src/pages/login.css
@@ -30,7 +30,7 @@
 
 #instances-suggestions {
   margin: 0.2em 0 0;
-  padding: 0;
+  padding: 0 0 0 1.2em;
   list-style: none;
   width: 90vw;
   max-width: 40em;
diff --git a/src/pages/login.jsx b/src/pages/login.jsx
index ce5ec8c0..307fb112 100644
--- a/src/pages/login.jsx
+++ b/src/pages/login.jsx
@@ -3,6 +3,8 @@ import './login.css';
 import { useEffect, useRef, useState } from 'preact/hooks';
 import { useSearchParams } from 'react-router-dom';
 
+import logo from '../assets/logo.svg';
+
 import Link from '../components/link';
 import Loader from '../components/loader';
 import instancesListURL from '../data/instances.json?url';
@@ -42,6 +44,7 @@ function Login() {
   // }, []);
 
   const submitInstance = (instanceURL) => {
+    if (!instanceURL) return;
     store.local.set('instanceURL', instanceURL);
 
     (async () => {
@@ -72,23 +75,18 @@ function Login() {
     })();
   };
 
-  const onSubmit = (e) => {
-    e.preventDefault();
-    const { elements } = e.target;
-    let instanceURL = elements.instanceURL.value.toLowerCase();
-    // Remove protocol from instance URL
-    instanceURL = instanceURL.replace(/^https?:\/\//, '').replace(/\/+$/, '');
-    // Remove @acct@ or acct@ from instance URL
-    instanceURL = instanceURL.replace(/^@?[^@]+@/, '');
-    if (!/\./.test(instanceURL)) {
-      instanceURL = instancesList.find((instance) =>
-        instance.includes(instanceURL),
-      );
-    }
-    submitInstance(instanceURL);
-  };
+  const cleanInstanceText = instanceText
+    ? instanceText
+        .replace(/^https?:\/\//, '') // Remove protocol from instance URL
+        .replace(/\/+$/, '') // Remove trailing slash
+        .replace(/^@?[^@]+@/, '') // Remove @?acct@
+        .trim()
+    : null;
+  const instanceTextLooksLikeDomain =
+    /[^\s\r\n\t\/\\]+\.[^\s\r\n\t\/\\]+/.test(cleanInstanceText) &&
+    !/[\s\/\\@]/.test(cleanInstanceText);
 
-  const instancesSuggestions = instanceText
+  const instancesSuggestions = cleanInstanceText
     ? instancesList
         .filter((instance) => instance.includes(instanceText))
         .sort((a, b) => {
@@ -106,10 +104,39 @@ function Login() {
         .slice(0, 10)
     : [];
 
+  const selectedInstanceText = instanceTextLooksLikeDomain
+    ? cleanInstanceText
+    : instancesSuggestions?.length
+    ? instancesSuggestions[0]
+    : instanceText
+    ? instancesList.find((instance) => instance.includes(instanceText))
+    : null;
+
+  const onSubmit = (e) => {
+    e.preventDefault();
+    // const { elements } = e.target;
+    // let instanceURL = elements.instanceURL.value.toLowerCase();
+    // // Remove protocol from instance URL
+    // instanceURL = instanceURL.replace(/^https?:\/\//, '').replace(/\/+$/, '');
+    // // Remove @acct@ or acct@ from instance URL
+    // instanceURL = instanceURL.replace(/^@?[^@]+@/, '');
+    // if (!/\./.test(instanceURL)) {
+    //   instanceURL = instancesList.find((instance) =>
+    //     instance.includes(instanceURL),
+    //   );
+    // }
+    // submitInstance(instanceURL);
+    submitInstance(selectedInstanceText);
+  };
+
   return (
     <main id="login" style={{ textAlign: 'center' }}>
       <form onSubmit={onSubmit}>
-        <h1>Log in</h1>
+        <h1>
+          <img src={logo} alt="" width="80" height="80" />
+          <br />
+          Log in
+        </h1>
         <label>
           <p>Instance</p>
           <input
@@ -132,11 +159,11 @@ function Login() {
           />
           {instancesSuggestions?.length > 0 ? (
             <ul id="instances-suggestions">
-              {instancesSuggestions.map((instance) => (
+              {instancesSuggestions.map((instance, i) => (
                 <li>
                   <button
                     type="button"
-                    class="plain4"
+                    class="plain5"
                     onClick={() => {
                       submitInstance(instance);
                     }}
@@ -147,7 +174,7 @@ function Login() {
               ))}
             </ul>
           ) : (
-            <div id="instances-eg">e.g. &ldquo;mastodon.social&rsquo;</div>
+            <div id="instances-eg">e.g. &ldquo;mastodon.social&rdquo;</div>
           )}
           {/* <datalist id="instances-list">
             {instancesList.map((instance) => (
@@ -161,8 +188,14 @@ function Login() {
           </p>
         )}
         <div>
-          <button class="large" disabled={uiState === 'loading'}>
-            Log in
+          <button
+            disabled={
+              uiState === 'loading' || !instanceText || !selectedInstanceText
+            }
+          >
+            {selectedInstanceText
+              ? `Continue with ${selectedInstanceText}`
+              : 'Continue'}
           </button>{' '}
         </div>
         <Loader hidden={uiState !== 'loading'} />
diff --git a/src/pages/welcome.css b/src/pages/welcome.css
index 7c391744..d65f73b0 100644
--- a/src/pages/welcome.css
+++ b/src/pages/welcome.css
@@ -1,15 +1,3 @@
-@keyframes shine2 {
-  0% {
-    left: -100%;
-  }
-  20% {
-    left: 100%;
-  }
-  100% {
-    left: 100%;
-  }
-}
-
 #welcome {
   text-align: center;
   background-image: radial-gradient(
@@ -35,45 +23,23 @@
     flex-direction: column;
   }
 
+  .hero-content {
+    flex-grow: 1;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+  }
+
   h1 {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
     margin: 0;
     padding: 0;
     font-size: 5em;
     line-height: 1;
     letter-spacing: -1px;
-    flex-grow: 1;
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    align-items: center;
     position: relative;
-    mix-blend-mode: multiply;
-
-    @media (prefers-color-scheme: dark) {
-      mix-blend-mode: normal;
-    }
-
-    &:before {
-      content: '';
-      position: absolute;
-      z-index: 2;
-      width: 100%;
-      height: 100%;
-      background-image: linear-gradient(
-        100deg,
-        rgba(255, 255, 255, 0) 30%,
-        rgba(255, 255, 255, 0.4),
-        rgba(255, 255, 255, 0) 70%
-      );
-      top: 0;
-      left: -100%;
-      pointer-events: none;
-      animation: shine2 5s ease-in-out 1s infinite;
-
-      @media (prefers-color-scheme: dark) {
-        content: none;
-      }
-    }
 
     img {
       filter: drop-shadow(-1px -1px var(--bg-blur-color))
@@ -99,6 +65,10 @@
     font-size: 1.4em;
     text-wrap: balance;
     opacity: 0.7;
+
+    & ~ p {
+      margin-top: 0;
+    }
   }
 
   .hero-container > p {
@@ -148,25 +118,34 @@
   }
 
   @media (width > 40em) {
-    display: grid;
+    /* display: grid;
     grid-template-columns: 1fr 1fr;
-    grid-template-rows: 1fr auto;
     height: 100vh;
-    height: 100svh;
+    height: 100svh; */
+    width: 100%;
 
     .hero-container {
       height: auto;
+      max-height: none;
+      position: fixed;
+      left: 0;
+      top: 0;
+      bottom: 0;
+      width: 50%;
+      align-items: flex-end;
+
+      > * {
+        max-width: 40em;
+        width: 100%;
+      }
     }
 
     #why-container {
-      padding: 32px;
-      overflow: auto;
-      mask-image: linear-gradient(to top, transparent 16px, black 64px);
-    }
+      padding: 32px 32px 32px 8px;
+      margin-left: 50%;
 
-    footer {
-      grid-row: 2;
-      grid-column: 1 / span 2;
+      /* overflow: auto;
+      mask-image: linear-gradient(to top, transparent 16px, black 64px); */
     }
   }
 
diff --git a/src/pages/welcome.jsx b/src/pages/welcome.jsx
index 58882dcb..5319e60e 100644
--- a/src/pages/welcome.jsx
+++ b/src/pages/welcome.jsx
@@ -17,29 +17,58 @@ function Welcome() {
   return (
     <main id="welcome">
       <div class="hero-container">
-        <h1>
-          <img
-            src={logo}
-            alt=""
-            width="200"
-            height="200"
-            style={{
-              aspectRatio: '1/1',
-              marginBlockEnd: -16,
-            }}
-          />
-          <img src={logoText} alt="Phanpy" width="250" />
-        </h1>
+        <div class="hero-content">
+          <h1>
+            <img
+              src={logo}
+              alt=""
+              width="160"
+              height="160"
+              style={{
+                aspectRatio: '1/1',
+                marginBlockEnd: -16,
+              }}
+            />
+            <img src={logoText} alt="Phanpy" width="200" />
+          </h1>
+          <p class="desc">A minimalistic opinionated Mastodon web client.</p>
+          <p>
+            <Link to="/login" class="button">
+              Log in with Mastodon
+            </Link>
+          </p>
+          <p class="insignificant">
+            <small>
+              Connect your existing Mastodon/Fediverse account.
+              <br />
+              Your credentials are not stored on this server.
+            </small>
+          </p>
+        </div>
         <p>
-          <big>
-            <b>
-              <Link to="/login" class="button">
-                Log in
-              </Link>
-            </b>
-          </big>
+          <a href="https://github.com/cheeaun/phanpy" target="_blank">
+            Built
+          </a>{' '}
+          by{' '}
+          <a
+            href="https://mastodon.social/@cheeaun"
+            target="_blank"
+            onClick={(e) => {
+              e.preventDefault();
+              states.showAccount = 'cheeaun@mastodon.social';
+            }}
+          >
+            @cheeaun
+          </a>
+          .{' '}
+          <a
+            href="https://github.com/cheeaun/phanpy/blob/main/PRIVACY.MD"
+            target="_blank"
+          >
+            Privacy Policy
+          </a>
+          .
         </p>
-        <p class="desc">A minimalistic opinionated Mastodon web client.</p>
       </div>
       <div id="why-container">
         <div class="sections">
@@ -98,33 +127,6 @@ function Welcome() {
           </section>
         </div>
       </div>
-      <footer>
-        <hr />
-        <p>
-          <a href="https://github.com/cheeaun/phanpy" target="_blank">
-            Built
-          </a>{' '}
-          by{' '}
-          <a
-            href="https://mastodon.social/@cheeaun"
-            target="_blank"
-            onClick={(e) => {
-              e.preventDefault();
-              states.showAccount = 'cheeaun@mastodon.social';
-            }}
-          >
-            @cheeaun
-          </a>
-          .{' '}
-          <a
-            href="https://github.com/cheeaun/phanpy/blob/main/PRIVACY.MD"
-            target="_blank"
-          >
-            Privacy Policy
-          </a>
-          .
-        </p>
-      </footer>
     </main>
   );
 }