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. “mastodon.social’</div> + <div id="instances-eg">e.g. “mastodon.social”</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> ); }