mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Add cypress tests
This commit is contained in:
parent
744f42a65f
commit
bc88d341d4
7
cypress.config.ts
Normal file
7
cypress.config.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import {defineConfig} from "cypress"
|
||||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
baseUrl: "http://localhost:5173",
|
||||
},
|
||||
})
|
21
cypress/e2e/feed.cy.ts
Normal file
21
cypress/e2e/feed.cy.ts
Normal file
@ -0,0 +1,21 @@
|
||||
describe("feed interaction", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("/")
|
||||
})
|
||||
|
||||
it("clicking a card works", () => {
|
||||
cy.get(".cy-note-click-target:first").click()
|
||||
cy.get(".modal .fa-heart")
|
||||
cy.get(".modal .cy-modal-close").click()
|
||||
|
||||
cy.get(".modal").should("not.exist")
|
||||
})
|
||||
|
||||
it("feed controls works", () => {
|
||||
cy.get(".fa-sliders").click()
|
||||
cy.get(".modal .cy-chip:first .fa-times").click()
|
||||
cy.get(".modal").contains("Apply Filters").click()
|
||||
cy.contains("Kinds 30023,")
|
||||
cy.get(".card", {timeout: 30000})
|
||||
})
|
||||
})
|
12
cypress/e2e/login.cy.ts
Normal file
12
cypress/e2e/login.cy.ts
Normal file
@ -0,0 +1,12 @@
|
||||
describe("authenticated usage", () => {
|
||||
beforeEach(() => {
|
||||
cy.login()
|
||||
})
|
||||
|
||||
it("works", () => {
|
||||
cy.visit("/")
|
||||
cy.get("svg.logo").click()
|
||||
cy.get(".card").contains("Profile").click()
|
||||
cy.get(".cy-person-name").contains("test account 12938740")
|
||||
})
|
||||
})
|
10
cypress/e2e/search.cy.ts
Normal file
10
cypress/e2e/search.cy.ts
Normal file
@ -0,0 +1,10 @@
|
||||
describe("search", () => {
|
||||
it("works", () => {
|
||||
cy.visit("/")
|
||||
cy.get(".cy-top-nav .fa-search").click()
|
||||
cy.get(".cy-top-nav input").type("hodlbod")
|
||||
cy.get(".modal").contains("hodlbod").click()
|
||||
cy.get(".modal").contains("following")
|
||||
cy.get(".modal").contains("followers")
|
||||
})
|
||||
})
|
23
cypress/e2e/signup.cy.ts
Normal file
23
cypress/e2e/signup.cy.ts
Normal file
@ -0,0 +1,23 @@
|
||||
describe("signup", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("/")
|
||||
})
|
||||
|
||||
it("works", () => {
|
||||
cy.get(".cy-top-nav").contains("Log In").click()
|
||||
cy.get(".modal").contains("Sign Up").click()
|
||||
cy.get(".modal").contains("Let's go!").click()
|
||||
cy.get(".modal [name=name]").type("9sd2j3e0sd")
|
||||
cy.get(".modal").contains("Continue").click()
|
||||
cy.get(".modal").contains("Got it").click()
|
||||
cy.get(".modal").contains("Continue").click()
|
||||
cy.get(".modal").contains("Continue").click()
|
||||
cy.wait(1000)
|
||||
cy.get(".modal").contains("Skip and see your feed").click()
|
||||
cy.get(".modal").should("not.exist")
|
||||
cy.contains("From follows")
|
||||
cy.get("svg.logo").click()
|
||||
cy.get(".card").contains("Profile").click()
|
||||
cy.get(".cy-person-name").contains("9sd2j3e0sd")
|
||||
})
|
||||
})
|
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
29
cypress/support/commands.ts
Normal file
29
cypress/support/commands.ts
Normal file
@ -0,0 +1,29 @@
|
||||
const nsec = "nsec1er8narhat3xjypf46pksxlr6k4jrmv2e9psazjk0adynly0l4ltsepvmy5"
|
||||
|
||||
Cypress.Commands.add("login", () => {
|
||||
cy.session(
|
||||
nsec,
|
||||
() => {
|
||||
cy.visit("/login/privkey")
|
||||
cy.get("input[type=password]").type(nsec, {log: false})
|
||||
cy.get(".cy-login-submit").click()
|
||||
cy.get(".modal", {timeout: 10_000}).should("not.exist")
|
||||
cy.contains("Don't have an account?").should("not.exist")
|
||||
},
|
||||
{
|
||||
validate: () => {
|
||||
let pubkey
|
||||
|
||||
cy.window()
|
||||
.then(w => {
|
||||
pubkey = w.pubkey.get()
|
||||
})
|
||||
.then(() => {
|
||||
expect(pubkey).to.equal(
|
||||
"c853d879b7376dab1cdcd4faf235a05f680aae42ba620abdd95d619542a5a379"
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
20
cypress/support/e2e.ts
Normal file
20
cypress/support/e2e.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import "./commands"
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
@ -23,6 +23,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"cypress": "^13.3.1",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"postcss": "^8.4.19",
|
||||
@ -55,6 +56,7 @@
|
||||
"insane": "^2.6.2",
|
||||
"lru-cache": "^7.18.3",
|
||||
"marked": "^5.1.0",
|
||||
"normalize-url": "^8.0.0",
|
||||
"nostr-tools": "^1.12.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"paravel": "^0.3.7",
|
||||
|
@ -2,7 +2,7 @@
|
||||
import "@fortawesome/fontawesome-free/css/fontawesome.css"
|
||||
import "@fortawesome/fontawesome-free/css/solid.css"
|
||||
|
||||
import {nip19} from "nostr-tools"
|
||||
import {nip19, getPublicKey, generatePrivateKey} from "nostr-tools"
|
||||
import {pluck} from "ramda"
|
||||
import {seconds, Fetch} from "hurdak"
|
||||
import {tryFetch, hexToBech32, bech32ToHex, now} from "src/util/misc"
|
||||
@ -223,7 +223,15 @@
|
||||
|
||||
// Globals
|
||||
|
||||
Object.assign(window, {...engine, nip19, bech32ToHex, hexToBech32, router})
|
||||
Object.assign(window, {
|
||||
...engine,
|
||||
nip19,
|
||||
bech32ToHex,
|
||||
hexToBech32,
|
||||
router,
|
||||
getPublicKey,
|
||||
generatePrivateKey,
|
||||
})
|
||||
|
||||
// Theme
|
||||
|
||||
|
@ -156,8 +156,8 @@
|
||||
}} />
|
||||
|
||||
<div
|
||||
class="fixed top-0 z-10 flex h-16 w-full items-center justify-between border-b
|
||||
border-gray-6 bg-gray-7 px-2 text-gray-2">
|
||||
class="cy-top-nav fixed top-0 z-10 flex h-16 w-full items-center justify-between
|
||||
border-b border-gray-6 bg-gray-7 px-2 text-gray-2">
|
||||
<div>
|
||||
<div class="app-logo flex cursor-pointer items-center gap-2" on:click={toggleMenu}>
|
||||
<!-- <img alt="App Logo" src={logoUrl} class="w-10" /> -->
|
||||
@ -183,7 +183,7 @@
|
||||
<div
|
||||
class={cx(
|
||||
"search-input pointer-events-none fixed top-0 z-10 w-full px-2 text-gray-1",
|
||||
"flex h-16 items-center justify-end gap-4",
|
||||
"cy-top-nav flex h-16 items-center justify-end gap-4",
|
||||
{
|
||||
"pr-16": $session,
|
||||
"pr-28": !$session,
|
||||
|
@ -223,7 +223,7 @@
|
||||
</div>
|
||||
{#if muted}
|
||||
<p class="border-l-2 border-solid border-gray-6 pl-4 text-gray-1">
|
||||
You have muted this note.
|
||||
You have hidden this note.
|
||||
<Anchor
|
||||
theme="anchor"
|
||||
on:click={() => {
|
||||
@ -233,10 +233,12 @@
|
||||
{:else}
|
||||
<NoteContent {anchorId} note={event} {showEntire} />
|
||||
{/if}
|
||||
<div class="cy-note-click-target h-px" />
|
||||
<NoteActions
|
||||
note={event}
|
||||
bind:this={actions}
|
||||
{removeFromContext}
|
||||
{showMuted}
|
||||
{replies}
|
||||
{likes}
|
||||
{zaps}
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
export let note: Event
|
||||
export let reply
|
||||
export let showMuted
|
||||
export let showEntire
|
||||
export let removeFromContext
|
||||
export let replies
|
||||
@ -102,7 +103,7 @@
|
||||
let showDetails = false
|
||||
let actions = []
|
||||
|
||||
$: disableActions = !$canSign || $muted
|
||||
$: disableActions = !$canSign || ($muted && !showMuted)
|
||||
$: like = like || find(propEq("pubkey", $session?.pubkey), likes)
|
||||
$: allLikes = like ? likes.filter(n => n.id !== like?.id).concat(like) : likes
|
||||
$: $likesCount = allLikes.length
|
||||
|
@ -79,7 +79,7 @@
|
||||
{:else if quote}
|
||||
{#if muted}
|
||||
<p class="mb-1 py-24 text-center text-gray-5">
|
||||
You have muted this note.
|
||||
You have hidden this note.
|
||||
<Anchor class="underline" on:click={unmute}>Show</Anchor>
|
||||
</p>
|
||||
{:else}
|
||||
|
@ -30,7 +30,7 @@
|
||||
</script>
|
||||
|
||||
<div class={cx("flex items-center gap-1", $$props.class)}>
|
||||
<span>{displayPerson($person)}</span>
|
||||
<span class="cy-person-name">{displayPerson($person)}</span>
|
||||
<div class="flex items-center gap-1 font-normal">
|
||||
{#if $following}
|
||||
<span class="px-2 py-1 text-xs">
|
||||
|
@ -15,13 +15,13 @@
|
||||
loginWithExtension(await ext.getPublicKey())
|
||||
boot()
|
||||
} else {
|
||||
router.at("login/privkey").open()
|
||||
router.at("login/privkey").replaceModal()
|
||||
}
|
||||
})
|
||||
|
||||
const signUp = () => router.at("onboarding").open()
|
||||
const signUp = () => router.at("onboarding").replaceModal()
|
||||
|
||||
const advancedLogIn = () => router.at("login/advanced").open()
|
||||
const advancedLogIn = () => router.at("login/advanced").replaceModal()
|
||||
|
||||
document.title = "Log In"
|
||||
</script>
|
||||
|
@ -131,13 +131,15 @@
|
||||
<Spinner />
|
||||
{:else if Object.values(currentRelays).length > 0}
|
||||
<p>Currently searching:</p>
|
||||
{#each Object.values(currentRelays) as relay}
|
||||
<div class="h-12">
|
||||
{#if relay}
|
||||
<RelayCard hideActions relay={{...relay, description: null}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
<Content gap="gap-4" size="inherit">
|
||||
{#each Object.values(currentRelays) as relay}
|
||||
<div class="h-12">
|
||||
{#if relay}
|
||||
<RelayCard hideActions relay={{...relay, description: null}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</Content>
|
||||
{/if}
|
||||
</Content>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
<i slot="before" class="fa fa-key" />
|
||||
</Input>
|
||||
</div>
|
||||
<Anchor theme="button" on:click={logIn}>Log In</Anchor>
|
||||
<Anchor theme="button" class="cy-login-submit" on:click={logIn}>Log In</Anchor>
|
||||
</div>
|
||||
{#if !Capacitor.isNativePlatform()}
|
||||
<p class="rounded border-2 border-solid border-warning bg-gray-8 px-6 py-3">
|
||||
|
@ -1,8 +1,9 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {generatePrivateKey} from "nostr-tools"
|
||||
import {closure} from "hurdak"
|
||||
import {closure, sleep} from "hurdak"
|
||||
import {fly} from "src/util/transition"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import OnboardingIntro from "src/app/views/OnboardingIntro.svelte"
|
||||
import OnboardingProfile from "src/app/views/OnboardingProfile.svelte"
|
||||
import OnboardingKey from "src/app/views/OnboardingKey.svelte"
|
||||
@ -62,6 +63,13 @@
|
||||
})
|
||||
|
||||
const signup = async noteContent => {
|
||||
// Go to our home page
|
||||
router.at("notes").push()
|
||||
|
||||
// Make things async since the `key` change in App.svelte prevents the modal
|
||||
// animation from completing, and it gets stuck. This is a svelte bug
|
||||
await sleep(10)
|
||||
|
||||
loginWithPrivateKey(privkey)
|
||||
|
||||
// Do this first so we know where to publish everything else
|
||||
@ -78,12 +86,6 @@
|
||||
|
||||
// Start our notifications listener
|
||||
listenForNotifications()
|
||||
|
||||
// Close all modals
|
||||
router.clearModals()
|
||||
|
||||
// Go to our home page
|
||||
router.at("notes").push()
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
@ -94,18 +96,20 @@
|
||||
|
||||
{#key stage}
|
||||
<div in:fly={{y: 20}}>
|
||||
{#if stage === "intro"}
|
||||
<OnboardingIntro {setStage} />
|
||||
{:else if stage === "profile"}
|
||||
<OnboardingProfile {setStage} {profile} />
|
||||
{:else if stage === "key"}
|
||||
<OnboardingKey {setStage} {privkey} />
|
||||
{:else if stage === "relays"}
|
||||
<OnboardingRelays {setStage} bind:relays />
|
||||
{:else if stage === "follows"}
|
||||
<OnboardingFollows {setStage} bind:petnames />
|
||||
{:else if stage === "note"}
|
||||
<OnboardingNote {setStage} {signup} />
|
||||
{/if}
|
||||
<Content size="lg">
|
||||
{#if stage === "intro"}
|
||||
<OnboardingIntro {setStage} />
|
||||
{:else if stage === "profile"}
|
||||
<OnboardingProfile {setStage} {profile} />
|
||||
{:else if stage === "key"}
|
||||
<OnboardingKey {setStage} {privkey} />
|
||||
{:else if stage === "relays"}
|
||||
<OnboardingRelays {setStage} bind:relays />
|
||||
{:else if stage === "follows"}
|
||||
<OnboardingFollows {setStage} bind:petnames />
|
||||
{:else if stage === "note"}
|
||||
<OnboardingNote {setStage} {signup} />
|
||||
{/if}
|
||||
</Content>
|
||||
</div>
|
||||
{/key}
|
||||
|
@ -3,7 +3,6 @@
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import PersonSummary from "src/app/shared/PersonSummary.svelte"
|
||||
import type {Person} from "src/engine"
|
||||
import {env, mention, loadPeople, searchPeople} from "src/engine"
|
||||
@ -29,58 +28,54 @@
|
||||
$: results = reject((p: Person) => pubkeys.includes(p.pubkey), $searchPeople(q))
|
||||
</script>
|
||||
|
||||
<Content>
|
||||
<Content class="text-center">
|
||||
<Heading>Find Your People</Heading>
|
||||
<p>
|
||||
To get you started, we’ve added some interesting people to your follow list. You can update
|
||||
your follows list at any time.
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
</div>
|
||||
</Content>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-user-astronaut fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Your follows</h2>
|
||||
<Heading class="text-center">Find Your People</Heading>
|
||||
<p>
|
||||
To get you started, we’ve added some interesting people to your follow list. You can update your
|
||||
follows list at any time.
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-user-astronaut fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Your follows</h2>
|
||||
</div>
|
||||
{#if pubkeys.length === 0}
|
||||
<div class="mt-8 flex items-center justify-center gap-2 text-center">
|
||||
<i class="fa fa-triangle-exclamation" />
|
||||
<span>No follows selected</span>
|
||||
</div>
|
||||
{#if pubkeys.length === 0}
|
||||
<div class="mt-8 flex items-center justify-center gap-2 text-center">
|
||||
<i class="fa fa-triangle-exclamation" />
|
||||
<span>No follows selected</span>
|
||||
</div>
|
||||
{:else}
|
||||
{#each pubkeys as pubkey (pubkey)}
|
||||
<PersonSummary {pubkey}>
|
||||
<div slot="actions" class="flex items-start justify-end">
|
||||
<Anchor
|
||||
theme="button"
|
||||
class="flex items-center gap-2"
|
||||
on:click={() => removeFollow(pubkey)}>
|
||||
<i class="fa fa-user-slash" /> Unfollow
|
||||
</Anchor>
|
||||
</div>
|
||||
</PersonSummary>
|
||||
{/each}
|
||||
{/if}
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-earth-asia fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Other people</h2>
|
||||
</div>
|
||||
<Input bind:value={q} type="text" wrapperClass="flex-grow" placeholder="Type to search">
|
||||
<i slot="before" class="fa-solid fa-search" />
|
||||
</Input>
|
||||
{#each results.slice(0, 50) as profile (profile.pubkey)}
|
||||
<PersonSummary pubkey={profile.pubkey}>
|
||||
{:else}
|
||||
{#each pubkeys as pubkey (pubkey)}
|
||||
<PersonSummary {pubkey}>
|
||||
<div slot="actions" class="flex items-start justify-end">
|
||||
<Anchor
|
||||
theme="button-accent"
|
||||
theme="button"
|
||||
class="flex items-center gap-2"
|
||||
on:click={() => addFollow(profile.pubkey)}>
|
||||
<i class="fa fa-user-plus" /> Follow
|
||||
on:click={() => removeFollow(pubkey)}>
|
||||
<i class="fa fa-user-slash" /> Unfollow
|
||||
</Anchor>
|
||||
</div>
|
||||
</PersonSummary>
|
||||
{/each}
|
||||
</Content>
|
||||
{/if}
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-earth-asia fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Other people</h2>
|
||||
</div>
|
||||
<Input bind:value={q} type="text" wrapperClass="flex-grow" placeholder="Type to search">
|
||||
<i slot="before" class="fa-solid fa-search" />
|
||||
</Input>
|
||||
{#each results.slice(0, 50) as profile (profile.pubkey)}
|
||||
<PersonSummary pubkey={profile.pubkey}>
|
||||
<div slot="actions" class="flex items-start justify-end">
|
||||
<Anchor
|
||||
theme="button-accent"
|
||||
class="flex items-center gap-2"
|
||||
on:click={() => addFollow(profile.pubkey)}>
|
||||
<i class="fa fa-user-plus" /> Follow
|
||||
</Anchor>
|
||||
</div>
|
||||
</PersonSummary>
|
||||
{/each}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
|
||||
export let setStage
|
||||
|
||||
@ -10,16 +9,14 @@
|
||||
const next = () => setStage("profile")
|
||||
</script>
|
||||
|
||||
<Content size="lg" class="text-center">
|
||||
<Heading>Create an Account</Heading>
|
||||
<p>
|
||||
New to Nostr? Click <Anchor class="underline" external href={tutorialUrl}>here</Anchor> or watch
|
||||
the video below for a crash course on what it is, and how to use it.
|
||||
</p>
|
||||
<video controls src={videoUrl} class="object-contain object-center" />
|
||||
<p>
|
||||
When you’re ready to dive in, click below and we’ll guide you through the process of creating an
|
||||
account.
|
||||
</p>
|
||||
<Anchor theme="button-accent" on:click={next}>Let's go!</Anchor>
|
||||
</Content>
|
||||
<Heading class="text-center">Create an Account</Heading>
|
||||
<p>
|
||||
New to Nostr? Click <Anchor class="underline" external href={tutorialUrl}>here</Anchor> or watch the
|
||||
video below for a crash course on what it is, and how to use it.
|
||||
</p>
|
||||
<video controls src={videoUrl} class="object-contain object-center" />
|
||||
<p>
|
||||
When you’re ready to dive in, click below and we’ll guide you through the process of creating an
|
||||
account.
|
||||
</p>
|
||||
<Anchor theme="button-accent" class="text-center" on:click={next}>Let's go!</Anchor>
|
||||
|
@ -5,7 +5,6 @@
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import {env} from "src/engine"
|
||||
|
||||
export let privkey
|
||||
@ -21,19 +20,17 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Content size="lg" class="text-center">
|
||||
<Heading>Generate a Key</Heading>
|
||||
<p>
|
||||
Your private key is your password, and gives you total control over your Nostr account. We've
|
||||
generated a fresh one for you below – store it somewhere safe!
|
||||
</p>
|
||||
<Input disabled placeholder={"•".repeat(53)} wrapperClass="flex-grow">
|
||||
<i slot="before" class="fa fa-lock" />
|
||||
<button slot="after" class="fa fa-copy cursor-pointer" on:click={copyKey} />
|
||||
</Input>
|
||||
<p>If you don't want to save your keys now, you can find them later in {appName}'s settings.</p>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Got it</Anchor>
|
||||
</div>
|
||||
</Content>
|
||||
<Heading class="text-center">Generate a Key</Heading>
|
||||
<p>
|
||||
Your private key is your password, and gives you total control over your Nostr account. We've
|
||||
generated a fresh one for you below – store it somewhere safe!
|
||||
</p>
|
||||
<Input disabled placeholder={"•".repeat(53)} wrapperClass="flex-grow">
|
||||
<i slot="before" class="fa fa-lock" />
|
||||
<button slot="after" class="fa fa-copy cursor-pointer" on:click={copyKey} />
|
||||
</Input>
|
||||
<p>If you don't want to save your keys now, you can find them later in {appName}'s settings.</p>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Got it</Anchor>
|
||||
</div>
|
||||
|
@ -3,7 +3,6 @@
|
||||
import Compose from "src/app/shared/Compose.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
|
||||
export let signup
|
||||
export let setStage
|
||||
@ -19,20 +18,18 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<Content size="lg">
|
||||
<Heading class="text-center">Welcome to Nostr</Heading>
|
||||
<p class="text-center">
|
||||
Your're all set! If have any questions, just ask! People around these parts are always ready to
|
||||
lend a hand.
|
||||
</p>
|
||||
<div class="border-l-2 border-solid border-gray-6 pl-4">
|
||||
<Compose bind:this={compose} onSubmit={next} />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Say Hello!</Anchor>
|
||||
</div>
|
||||
<Anchor class="text-center" on:click={skip}>
|
||||
Skip and see your feed <i class="fa fa-arrow-right" />
|
||||
</Anchor>
|
||||
</Content>
|
||||
<Heading class="text-center">Welcome to Nostr</Heading>
|
||||
<p>
|
||||
Your're all set! If have any questions, just ask! People around these parts are always ready to
|
||||
lend a hand.
|
||||
</p>
|
||||
<div class="border-l-2 border-solid border-gray-6 pl-4">
|
||||
<Compose bind:this={compose} onSubmit={next} />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Say Hello!</Anchor>
|
||||
</div>
|
||||
<Anchor class="text-center" on:click={skip}>
|
||||
Skip and see your feed <i class="fa fa-arrow-right" />
|
||||
</Anchor>
|
||||
|
@ -4,7 +4,6 @@
|
||||
import ImageInput from "src/partials/ImageInput.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
|
||||
export let profile
|
||||
export let setStage
|
||||
@ -13,35 +12,28 @@
|
||||
const next = () => setStage("key")
|
||||
</script>
|
||||
|
||||
<Content size="lg">
|
||||
<Heading class="text-center">Introduce Yourself</Heading>
|
||||
<p class="text-center">
|
||||
Give other people something to go on. Remember that "privacy is the power to selectively reveal
|
||||
oneself to the world".
|
||||
</p>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Your Name</strong>
|
||||
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={profile.name}>
|
||||
<i slot="before" class="fa-solid fa-user-astronaut" />
|
||||
</Input>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>About You</strong>
|
||||
<Textarea name="about" bind:value={profile.about} />
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Profile Picture</strong>
|
||||
<ImageInput
|
||||
bind:value={profile.picture}
|
||||
icon="image-portrait"
|
||||
maxWidth={480}
|
||||
maxHeight={480} />
|
||||
<p class="text-sm text-gray-1">Please be mindful of others and only use small images.</p>
|
||||
</div>
|
||||
<Heading class="text-center">Introduce Yourself</Heading>
|
||||
<p>
|
||||
Give other people something to go on. Remember that "privacy is the power to selectively reveal
|
||||
oneself to the world".
|
||||
</p>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Your Name</strong>
|
||||
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={profile.name}>
|
||||
<i slot="before" class="fa-solid fa-user-astronaut" />
|
||||
</Input>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>About You</strong>
|
||||
<Textarea name="about" bind:value={profile.about} />
|
||||
</div>
|
||||
</Content>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Profile Picture</strong>
|
||||
<ImageInput bind:value={profile.picture} icon="image-portrait" maxWidth={480} maxHeight={480} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
</div>
|
||||
|
@ -34,52 +34,50 @@
|
||||
)
|
||||
</script>
|
||||
|
||||
<Content>
|
||||
<div class="text-center">
|
||||
<Heading>Get Connected</Heading>
|
||||
<p>
|
||||
Nostr is a protocol, not a platform. This means that <i>you</i> choose where to store your data.
|
||||
Select your preferred storage relays below, or click "continue" to use some reasonable defaults.
|
||||
You can change your selection any time.
|
||||
</p>
|
||||
<Heading class="text-center">Get Connected</Heading>
|
||||
<p>
|
||||
Nostr is a protocol, not a platform. This means that <i>you</i> choose where to store your data.
|
||||
</p>
|
||||
<p>
|
||||
Select your preferred storage relays below, or click "continue" to use some reasonable defaults.
|
||||
You can change your selection any time.
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-server fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Your relays</h2>
|
||||
</div>
|
||||
{#if relays.length === 0}
|
||||
<div class="mt-8 flex items-center justify-center gap-2 text-center">
|
||||
<i class="fa fa-triangle-exclamation" />
|
||||
<span>No relays connected</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<Anchor theme="button" on:click={prev}><i class="fa fa-arrow-left" /></Anchor>
|
||||
<Anchor theme="button-accent" class="flex-grow text-center" on:click={next}>Continue</Anchor>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-server fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Your relays</h2>
|
||||
</div>
|
||||
{#if relays.length === 0}
|
||||
<div class="mt-8 flex items-center justify-center gap-2 text-center">
|
||||
<i class="fa fa-triangle-exclamation" />
|
||||
<span>No relays connected</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
{#each relays as relay (relay.url)}
|
||||
<RelayCard {relay}>
|
||||
<div slot="actions">
|
||||
{#if relays.length > 1}
|
||||
<button
|
||||
class="flex items-center gap-3 text-gray-1"
|
||||
on:click={() => removeRelay(relay)}>
|
||||
<i class="fa fa-right-from-bracket" /> Leave
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</RelayCard>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-earth-asia fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Other relays</h2>
|
||||
</div>
|
||||
<Input bind:value={q} type="text" wrapperClass="flex-grow" placeholder="Type to search">
|
||||
<i slot="before" class="fa-solid fa-search" />
|
||||
</Input>
|
||||
{:else}
|
||||
<Content gap="gap-4" size="inherit">
|
||||
{#each relays as relay (relay.url)}
|
||||
<RelayCard {relay}>
|
||||
<div slot="actions">
|
||||
{#if relays.length > 1}
|
||||
<button class="flex items-center gap-3 text-gray-1" on:click={() => removeRelay(relay)}>
|
||||
<i class="fa fa-right-from-bracket" /> Leave
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</RelayCard>
|
||||
{/each}
|
||||
</Content>
|
||||
{/if}
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-earth-asia fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Other relays</h2>
|
||||
</div>
|
||||
<Input bind:value={q} type="text" wrapperClass="flex-grow" placeholder="Type to search">
|
||||
<i slot="before" class="fa-solid fa-search" />
|
||||
</Input>
|
||||
<Content gap="gap-4" size="inherit">
|
||||
{#each (search(q) || []).slice(0, 50) as relay (relay.url)}
|
||||
<RelayCard {relay}>
|
||||
<div slot="actions">
|
||||
@ -89,8 +87,8 @@
|
||||
</div>
|
||||
</RelayCard>
|
||||
{/each}
|
||||
<small class="text-center">
|
||||
Showing {Math.min($knownRelays.length - relays.length, 50)}
|
||||
of {$knownRelays.length - relays.length} known relays
|
||||
</small>
|
||||
</Content>
|
||||
<small class="text-center">
|
||||
Showing {Math.min($knownRelays.length - relays.length, 50)}
|
||||
of {$knownRelays.length - relays.length} known relays
|
||||
</small>
|
||||
|
@ -4,10 +4,14 @@
|
||||
export let theme = "dark"
|
||||
export let onRemove = null
|
||||
|
||||
const className = cx($$props.class, "inline-block rounded-full border border-solid py-1 px-2", {
|
||||
"border-gray-1": theme === "dark",
|
||||
"border-gray-8": theme === "light",
|
||||
})
|
||||
const className = cx(
|
||||
$$props.class,
|
||||
"inline-block rounded-full border border-solid py-1 px-2 cy-chip",
|
||||
{
|
||||
"border-gray-1": theme === "dark",
|
||||
"border-gray-8": theme === "light",
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<div class={className}>
|
||||
|
@ -66,7 +66,7 @@
|
||||
<div
|
||||
class="pointer-events-auto flex h-10 w-10 cursor-pointer items-center justify-center rounded-full
|
||||
border border-solid border-accent-light bg-accent text-white transition-colors hover:bg-accent-light">
|
||||
<i class="fa fa-times fa-lg" />
|
||||
<i class="fa fa-times fa-lg cy-modal-close" />
|
||||
</div>
|
||||
{#if $modals.length > 1 && index > 0}
|
||||
<div
|
||||
|
@ -3,6 +3,7 @@
|
||||
"include": ["src/**/*"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "esnext",
|
||||
"paths": {
|
||||
"src/*": ["src/*"]
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user