web: added login page

It's a start, but nothing great.
This commit is contained in:
Thomas Mathews 2022-12-22 10:55:22 -08:00
parent ab2ced247b
commit cdb2fefe90
5 changed files with 195 additions and 21 deletions

View file

@ -28,6 +28,35 @@ a:visited {
padding: 15px;
}
/* Welcome */
#container-busy .loader {
height: 100vh;
}
.page-content {
max-width: 700px;
margin: 0 auto;
}
.hero-box {
width: 100vw;
height: 100vh;
}
.hero-box > .padded {
/* TODO rename .padded */
padding: 20px;
text-align: center;
position: relative;
top: 50%;
transform: translateY(-50%);
}
.btn-text {
border: none;
font-size: var(--fsNormal);
color: var(--clrText);
background: transparent;
text-decoration: underline;
}
/* Navigation */
#nav {
border-right: 1px solid var(--clrBorder);
@ -359,6 +388,9 @@ details.cw summary {
transition: opacity 0.2s linear;
backdrop-filter: blur(20px);
}
.modal.scrollable {
overflow: scroll;
}
.modal.closed {
opacity: 0;
pointer-events: none;
@ -383,6 +415,11 @@ details.cw summary {
.modal header button {
font-size: 24px;
}
.modal .modal-floating-close-btn {
position: sticky;
top: 20px;
left: 20px;
}
/* Post & Reply */
#newpost {

1
web/icon/key.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M227.3 265.9L141.3 352L182.6 393.4C195.1 405.9 195.1 426.1 182.6 438.6C170.1 451.1 149.9 451.1 137.4 438.6L96 397.3L77.25 416L118.6 457.4C131.1 469.9 131.1 490.1 118.6 502.6C106.1 515.1 85.87 515.1 73.37 502.6L9.372 438.6C-3.124 426.1-3.124 405.9 9.372 393.4L182.1 220.7C168.1 198.5 159.1 172.2 159.1 144C159.1 64.47 224.5 0 304 0C383.5 0 448 64.47 448 144C448 223.5 383.5 288 304 288C275.8 288 249.5 279.9 227.3 265.9H227.3zM304 224C348.2 224 384 188.2 384 144C384 99.82 348.2 64 304 64C259.8 64 224 99.82 224 144C224 188.2 259.8 224 304 224z"/></svg>

After

Width:  |  Height:  |  Size: 791 B

View file

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; connect-src 'self' ws: wss:; script-src 'self'; script-src-elem 'self' 'unsafe-inline'; script-src-attr 'unsafe-inline'; style-src 'self' fonts.googleapis.com; img-src http: https: data:; media-src *; font-src 'self' fonts.gstatic.com; child-src 'none';" />
content="default-src 'none'; connect-src 'self' ws: wss:; script-src 'self'; script-src-elem 'self'; script-src-attr 'unsafe-inline'; style-src 'self' fonts.googleapis.com; img-src http: https: data:; media-src *; font-src 'self' fonts.gstatic.com; child-src 'none';" />
<title>Damus</title>
<link rel="stylesheet" href="css/vars.css?v=1">
@ -26,18 +26,37 @@
<script defer src="js/event.js?v=1"></script>
<script defer src="js/unknowns.js?v=1"></script>
<script defer src="js/lib.js?v=1"></script>
<script defer src="js/damus.js?v=92"></script>
<script defer src="js/main.js?v=1"></script>
</head>
<body>
<script>
// This is our main entry.
// https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
addEventListener('DOMContentLoaded', (ev) => {
damus_web_init();
});
</script>
<div id="gsticker" title="This is alpha software.">αlpha</div>
<div id="container-busy">
<div class="loader" title="Loading...">
<img class="dark-invert" src="icon/loader-fragment.svg"/>
</div>
</div>
<div id="container-welcome" class="hide">
<div class="hero-box">
<div class="padded">
<h1>
Yo, Sup?
<img class="icon svg" src="icon/logo-inverted.svg"/>
</h1>
<p>The blue bird experience for Nostr.</p>
<button class="action" onclick="signin()">
Sign In with Key
<img src="./icon/key.svg" class="icon svg small dark-noinvert"/>
</button>
<br/>
<br/>
<button class="btn-text" onclick="open_faqs()">
What's Nostr?
</button>
</div>
</div>
</div>
<div id="container-app" class="hide">
<div id="gsticker" title="This is alpha software.">αlpha</div>
<nav id="gnav" class="">
<button class="icon" role="open-gnav" title="Open Menu" onclick="toggle_gnav(this)">
<img class="icon svg invert" src="icon/logo.svg"/>
@ -145,6 +164,7 @@
</div>
<div class="flex-fill vertical-hide"></div>
</div>
</div>
<div class="modal closed" id="media-preview">
<div class="media-container">
@ -173,5 +193,81 @@
</div>
</div>
</div>
<div id="faqs" class="modal scrollable closed">
<button class="icon modal-floating-close-btn" onclick="close_modal(this)">
<img class="icon svg" src="icon/close-modal.svg"/>
</button>
<div class="page-content">
<h1>Welcome to Nostr</h1>
<p>The open social network for "literally" everyone.</p>
<h2>What is Nostr?</h2>
<p>
Nostr is a protocol, not a platform or an app. This means that
users can pick and choose which clients (apps) to use and which
relays (servers) they wish to connect to.
</p>
<p>Nostr uses encryption to validate content authors. This means
that there is no centralized account system. We use
<a href="https://en.wikipedia.org/wiki/Public-key_cryptography"
target="_blank">public &amp; private</a> keys to sign our
content when we post. Do not confuse this with blockchain
technology.
</p>
<p>
Nostr stands for "Notes and Other Stuff Transmitted by Relays".
</p>
<p>
Read more about the protocol <a
href="https://github.com/nostr-protocol/nostr"
target="_blank">here</a>.
</p>
<h2>Apps</h2>
<p>
You are using one right now! You just haven't signed in yet to see
the actual application. Scroll to the top to do that.
</p>
<p>
A rich app ecosystem for Nostr. Anyone can build an app for the
protocol that fits their needs. This is the best option for users
as everyone has their own style. Another benifit is that you can
use multiple apps with the same account.
</p>
<p>
Since there are many apps for Nostr it allows developers to focus
on building certain experiences. Some apps may offer features that
others don't, such as direct messages, content viewing methods,
etc. You are allowed to choose how you want to interact with
Nostr.
</p>
<h3>Pick One</h3>
<p>
Here are a list of (trusted) apps that work with Nostr. Pick one
that fits you.
</p>
<ul>
<li>Yo, Sup (this web app)</li>
<li><a href="https://damus.io" target="_blank">Damus</a></li>
<li><a href="https://github.com/fiatjaf/noscl" target="_blank">noscl</a></li>
</ul>
<h2>Relays</h2>
<p>
Relays are points of connection, a server. They allow you to read
events (content) and write to it depending on it's configuration.
Some may be read only, others may require some sort of payment to
use. Some may simply clone other relays.
</p>
<p>
Relays allow for specific needs and niches. You can host your
own relay for your club or community (such as gaming, art, sciences,
etc.) Or you can build your own relay with your own logic that
dictates who can access what and how. This is great for all kinds
of use cases for a range of users from individuals to businesses.
</p>
</div>
</div>
</body>
</html>

View file

@ -1,4 +1,4 @@
let DAMUS
let DAMUS = new_model();
const BOOTSTRAP_RELAYS = [
"wss://relay.damus.io",
@ -17,6 +17,12 @@ const SID_NOTIFICATIONS = "notifications";
const SID_EXPLORE = "explore";
const SID_PROFILES = "profiles";
// This is our main entry.
// https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
addEventListener('DOMContentLoaded', (ev) => {
damus_web_init();
});
async function damus_web_init() {
init_message_textareas();
let tries = 0;
@ -36,13 +42,31 @@ async function damus_web_init() {
}
async function damus_web_init_ready() {
const model = new_model();
DAMUS = model;
model.pubkey = await get_pubkey();
const model = DAMUS;
model.pubkey = await get_pubkey(false);
find_node("#container-busy").classList.add("hide");
if (!model.pubkey) {
// TODO show welcome screen
find_node("#container-welcome").classList.remove("hide");
return;
}
find_node("#container-app").classList.remove("hide");
webapp_init();
}
async function signin() {
const model = DAMUS;
model.pubkey = await get_pubkey();
if (!model.pubkey) {
return;
}
find_node("#container-welcome").classList.add("hide");
find_node("#container-app").classList.remove("hide");
webapp_init();
}
async function webapp_init() {
const model = DAMUS;
// WARNING Order Matters!
view_show_spinner(true);

View file

@ -240,19 +240,21 @@ function update_title(model) {
update_notification_markers(has_notes)
}
async function get_pubkey() {
async function get_pubkey(use_prompt=true) {
let pubkey = get_local_state('pubkey')
if (pubkey)
return pubkey
if (window.nostr && window.nostr.getPublicKey) {
console.log("calling window.nostr.getPublicKey()...")
log_debug("calling window.nostr.getPublicKey()...")
const pubkey = await window.nostr.getPublicKey()
console.log("got %s pubkey from nos2x", pubkey)
log_debug("got %s pubkey from nos2x", pubkey)
return await handle_pubkey(pubkey)
}
pubkey = prompt("Enter nostr id (eg: jb55@jb55.com) or pubkey (hex or npub)")
if (!pubkey)
throw new Error("Need pubkey to continue")
if (!use_prompt)
return;
pubkey = prompt("Enter Nostr ID (eg: jb55@jb55.com) or public key (hex or npub).")
if (!pubkey.trim())
return;
return await handle_pubkey(pubkey)
}
@ -280,6 +282,20 @@ function open_profile(pubkey) {
view_update_profile(DAMUS, pubkey);
}
function open_faqs() {
find_node("#faqs").classList.remove("closed");
}
function close_modal(el) {
while (el.parentElement) {
if (el.classList.contains("modal")) {
el.classList.add("closed");
break;
}
el = el.parentElement;
}
}
function view_update_profile(model, pubkey) {
const profile = model.profiles[pubkey] || {};
const el = find_node("[role='profile-info']");