mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-29 04:39:20 +03:00
Adjustments to welcome and login pages
This commit is contained in:
parent
7dd0b0a4fb
commit
433d8b3bcc
5 changed files with 148 additions and 125 deletions
|
@ -242,6 +242,15 @@ button,
|
||||||
:is(button, .button).plain4:not(:disabled, .disabled):is(:hover, :focus) {
|
:is(button, .button).plain4:not(:disabled, .disabled):is(:hover, :focus) {
|
||||||
color: var(--text-color);
|
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 {
|
:is(button, .button).light {
|
||||||
background-color: var(--bg-faded-color);
|
background-color: var(--bg-faded-color);
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#instances-suggestions {
|
#instances-suggestions {
|
||||||
margin: 0.2em 0 0;
|
margin: 0.2em 0 0;
|
||||||
padding: 0;
|
padding: 0 0 0 1.2em;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
width: 90vw;
|
width: 90vw;
|
||||||
max-width: 40em;
|
max-width: 40em;
|
||||||
|
|
|
@ -3,6 +3,8 @@ import './login.css';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import logo from '../assets/logo.svg';
|
||||||
|
|
||||||
import Link from '../components/link';
|
import Link from '../components/link';
|
||||||
import Loader from '../components/loader';
|
import Loader from '../components/loader';
|
||||||
import instancesListURL from '../data/instances.json?url';
|
import instancesListURL from '../data/instances.json?url';
|
||||||
|
@ -42,6 +44,7 @@ function Login() {
|
||||||
// }, []);
|
// }, []);
|
||||||
|
|
||||||
const submitInstance = (instanceURL) => {
|
const submitInstance = (instanceURL) => {
|
||||||
|
if (!instanceURL) return;
|
||||||
store.local.set('instanceURL', instanceURL);
|
store.local.set('instanceURL', instanceURL);
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -72,23 +75,18 @@ function Login() {
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = (e) => {
|
const cleanInstanceText = instanceText
|
||||||
e.preventDefault();
|
? instanceText
|
||||||
const { elements } = e.target;
|
.replace(/^https?:\/\//, '') // Remove protocol from instance URL
|
||||||
let instanceURL = elements.instanceURL.value.toLowerCase();
|
.replace(/\/+$/, '') // Remove trailing slash
|
||||||
// Remove protocol from instance URL
|
.replace(/^@?[^@]+@/, '') // Remove @?acct@
|
||||||
instanceURL = instanceURL.replace(/^https?:\/\//, '').replace(/\/+$/, '');
|
.trim()
|
||||||
// Remove @acct@ or acct@ from instance URL
|
: null;
|
||||||
instanceURL = instanceURL.replace(/^@?[^@]+@/, '');
|
const instanceTextLooksLikeDomain =
|
||||||
if (!/\./.test(instanceURL)) {
|
/[^\s\r\n\t\/\\]+\.[^\s\r\n\t\/\\]+/.test(cleanInstanceText) &&
|
||||||
instanceURL = instancesList.find((instance) =>
|
!/[\s\/\\@]/.test(cleanInstanceText);
|
||||||
instance.includes(instanceURL),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
submitInstance(instanceURL);
|
|
||||||
};
|
|
||||||
|
|
||||||
const instancesSuggestions = instanceText
|
const instancesSuggestions = cleanInstanceText
|
||||||
? instancesList
|
? instancesList
|
||||||
.filter((instance) => instance.includes(instanceText))
|
.filter((instance) => instance.includes(instanceText))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
|
@ -106,10 +104,39 @@ function Login() {
|
||||||
.slice(0, 10)
|
.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 (
|
return (
|
||||||
<main id="login" style={{ textAlign: 'center' }}>
|
<main id="login" style={{ textAlign: 'center' }}>
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
<h1>Log in</h1>
|
<h1>
|
||||||
|
<img src={logo} alt="" width="80" height="80" />
|
||||||
|
<br />
|
||||||
|
Log in
|
||||||
|
</h1>
|
||||||
<label>
|
<label>
|
||||||
<p>Instance</p>
|
<p>Instance</p>
|
||||||
<input
|
<input
|
||||||
|
@ -132,11 +159,11 @@ function Login() {
|
||||||
/>
|
/>
|
||||||
{instancesSuggestions?.length > 0 ? (
|
{instancesSuggestions?.length > 0 ? (
|
||||||
<ul id="instances-suggestions">
|
<ul id="instances-suggestions">
|
||||||
{instancesSuggestions.map((instance) => (
|
{instancesSuggestions.map((instance, i) => (
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="plain4"
|
class="plain5"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
submitInstance(instance);
|
submitInstance(instance);
|
||||||
}}
|
}}
|
||||||
|
@ -147,7 +174,7 @@ function Login() {
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<div id="instances-eg">e.g. “mastodon.social’</div>
|
<div id="instances-eg">e.g. “mastodon.social”</div>
|
||||||
)}
|
)}
|
||||||
{/* <datalist id="instances-list">
|
{/* <datalist id="instances-list">
|
||||||
{instancesList.map((instance) => (
|
{instancesList.map((instance) => (
|
||||||
|
@ -161,8 +188,14 @@ function Login() {
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
<button class="large" disabled={uiState === 'loading'}>
|
<button
|
||||||
Log in
|
disabled={
|
||||||
|
uiState === 'loading' || !instanceText || !selectedInstanceText
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{selectedInstanceText
|
||||||
|
? `Continue with ${selectedInstanceText}`
|
||||||
|
: 'Continue'}
|
||||||
</button>{' '}
|
</button>{' '}
|
||||||
</div>
|
</div>
|
||||||
<Loader hidden={uiState !== 'loading'} />
|
<Loader hidden={uiState !== 'loading'} />
|
||||||
|
|
|
@ -1,15 +1,3 @@
|
||||||
@keyframes shine2 {
|
|
||||||
0% {
|
|
||||||
left: -100%;
|
|
||||||
}
|
|
||||||
20% {
|
|
||||||
left: 100%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#welcome {
|
#welcome {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
|
@ -35,45 +23,23 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 5em;
|
font-size: 5em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
letter-spacing: -1px;
|
letter-spacing: -1px;
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
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 {
|
img {
|
||||||
filter: drop-shadow(-1px -1px var(--bg-blur-color))
|
filter: drop-shadow(-1px -1px var(--bg-blur-color))
|
||||||
|
@ -99,6 +65,10 @@
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
|
||||||
|
& ~ p {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-container > p {
|
.hero-container > p {
|
||||||
|
@ -148,25 +118,34 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width > 40em) {
|
@media (width > 40em) {
|
||||||
display: grid;
|
/* display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
grid-template-rows: 1fr auto;
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
height: 100svh;
|
height: 100svh; */
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.hero-container {
|
.hero-container {
|
||||||
height: auto;
|
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 {
|
#why-container {
|
||||||
padding: 32px;
|
padding: 32px 32px 32px 8px;
|
||||||
overflow: auto;
|
margin-left: 50%;
|
||||||
mask-image: linear-gradient(to top, transparent 16px, black 64px);
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
/* overflow: auto;
|
||||||
grid-row: 2;
|
mask-image: linear-gradient(to top, transparent 16px, black 64px); */
|
||||||
grid-column: 1 / span 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,29 +17,58 @@ function Welcome() {
|
||||||
return (
|
return (
|
||||||
<main id="welcome">
|
<main id="welcome">
|
||||||
<div class="hero-container">
|
<div class="hero-container">
|
||||||
<h1>
|
<div class="hero-content">
|
||||||
<img
|
<h1>
|
||||||
src={logo}
|
<img
|
||||||
alt=""
|
src={logo}
|
||||||
width="200"
|
alt=""
|
||||||
height="200"
|
width="160"
|
||||||
style={{
|
height="160"
|
||||||
aspectRatio: '1/1',
|
style={{
|
||||||
marginBlockEnd: -16,
|
aspectRatio: '1/1',
|
||||||
}}
|
marginBlockEnd: -16,
|
||||||
/>
|
}}
|
||||||
<img src={logoText} alt="Phanpy" width="250" />
|
/>
|
||||||
</h1>
|
<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>
|
<p>
|
||||||
<big>
|
<a href="https://github.com/cheeaun/phanpy" target="_blank">
|
||||||
<b>
|
Built
|
||||||
<Link to="/login" class="button">
|
</a>{' '}
|
||||||
Log in
|
by{' '}
|
||||||
</Link>
|
<a
|
||||||
</b>
|
href="https://mastodon.social/@cheeaun"
|
||||||
</big>
|
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>
|
||||||
<p class="desc">A minimalistic opinionated Mastodon web client.</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="why-container">
|
<div id="why-container">
|
||||||
<div class="sections">
|
<div class="sections">
|
||||||
|
@ -98,33 +127,6 @@ function Welcome() {
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue