Spruce up scan/search/profile info/keys

This commit is contained in:
Jonathan Staab 2023-04-05 13:54:32 -05:00
parent b32a50ede9
commit 118d954de0
7 changed files with 80 additions and 95 deletions

View File

@ -4,13 +4,13 @@
- [ ] https://github.com/techfort/LokiJS
- Use indexed adapter github.com/techfort/LokiJS/blob/master/tutorials/Persistence%20Adapters.md and partitioning adapter
- Call close onbeforeunload to save pending changes
- Fix force relays on login: http://localhost:5173/messages/npub1l66wvfm7dxhd6wmvpukpjpyhvwtlxzu0qqajqxjfpr4rlfa8hl5qlkfr3q
- [ ] Fix iOS/safari/firefox
- [ ] Revisit profile page and info, include similar access to hex keys etc on notes, keys page
- [ ] Add full profile details to key page
- [ ] Make profile edit more obvious
- [ ] Maybe consolidate settings pages into several sections, each with a modal
- [ ] Revisit profile page and info
- [ ] include similar access to hex keys etc on notes
- [ ] Add zaps to likes tab
- [ ] Add like and zap details to note details
- [ ] Add hex key, like and zap info to note details
- [ ] Sort DMs, remember message status
- [ ] Image classification
- https://github.com/bhky/opennsfw2
- Requires updating my OS -_-

View File

@ -7,6 +7,7 @@
import Input from "src/partials/Input.svelte"
import Anchor from "src/partials/Anchor.svelte"
import Content from "src/partials/Content.svelte"
import Toggle from "src/partials/Toggle.svelte"
import Heading from "src/partials/Heading.svelte"
import keys from "src/agent/keys"
import {toast} from "src/app/ui"
@ -15,9 +16,13 @@
const nip07 = "https://github.com/nostr-protocol/nips/blob/master/07.md"
const keypairUrl = "https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/"
const copyKey = type => {
copyToClipboard(type === "private" ? nip19.nsecEncode($privkey) : nip19.npubEncode($pubkey))
let asHex = false
$: pubkeyDisplay = asHex ? $pubkey : nip19.npubEncode($pubkey)
$: privkeyDisplay = asHex || !$privkey ? $privkey : nip19.nsecEncode($privkey)
const copyKey = (type, value) => {
copyToClipboard(value)
toast.show("info", `Your ${type} key has been copied to the clipboard.`)
}
@ -32,7 +37,7 @@
<div in:fly={{y: 20}}>
<Content>
<div class="mb-4 flex flex-col items-center justify-center">
<div class="flex flex-col items-center justify-center">
<Heading>Your Keys</Heading>
<p>
Your account is identified across the network using a public/private <Anchor
@ -42,13 +47,22 @@
</p>
</div>
<div class="flex w-full flex-col gap-8">
<div class="flex flex-col gap-1">
<div class="flex items-center gap-2">
<strong>Show keys in hex format</strong>
<Toggle bind:value={asHex} />
</div>
<p class="text-sm text-gray-1">
Under the hood, Nostr uses a different encoding to represent keys.
</p>
</div>
<div class="flex flex-col gap-1">
<strong>Public Key</strong>
<Input disabled value={$pubkey ? nip19.npubEncode($pubkey) : ""}>
<Input disabled value={pubkeyDisplay}>
<button
slot="after"
class="fa-solid fa-copy cursor-pointer"
on:click={() => copyKey("public")} />
on:click={() => copyKey("public", pubkeyDisplay)} />
</Input>
<p class="text-sm text-gray-1">
Your public key identifies your account. You can share this with people trying to find you
@ -58,11 +72,11 @@
{#if $privkey}
<div class="flex flex-col gap-1">
<strong>Private Key</strong>
<Input disabled type="password" value={nip19.nsecEncode($privkey)}>
<Input disabled type="password" value={privkeyDisplay}>
<button
slot="after"
class="fa-solid fa-copy cursor-pointer"
on:click={() => copyKey("private")} />
on:click={() => copyKey("private", privkeyDisplay)} />
</Input>
<p class="text-sm text-gray-1">
Your private key is used to prove your identity by cryptographically signing messages. <strong

View File

@ -191,7 +191,7 @@
</div>
{/if}
</div>
<OverflowMenu size="xl" {actions} />
<OverflowMenu {actions} />
</div>
<PersonAbout {person} />
{#if person?.petnames}

View File

@ -4,6 +4,7 @@
import {navigate} from "svelte-routing"
import {find} from "ramda"
import {nip05, nip19} from "nostr-tools"
import Heading from "src/partials/Heading.svelte"
import Input from "src/partials/Input.svelte"
import Anchor from "src/partials/Anchor.svelte"
import Spinner from "src/partials/Spinner.svelte"
@ -62,8 +63,15 @@
</script>
<Content>
<div class="flex flex-col items-center justify-center">
<Heading>Find Something</Heading>
<p>
Enter any nostr identifier (npub, nevent, nprofile, note or user@domain.tld), or click on the
camera icon to scan with your device's camera instead.
</p>
</div>
<form class="flex gap-2" on:submit|preventDefault={() => handleInput(value)}>
<Input placeholder="nprofile..." bind:value wrapperClass="flex-grow" />
<Input placeholder="nprofile1..." bind:value wrapperClass="flex-grow" />
<Anchor type="button" on:click={() => handleInput(value)}>
<i class="fa fa-arrow-right" />
</Anchor>
@ -71,10 +79,6 @@
<i class="fa fa-camera" />
</Anchor>
</form>
<div class="text-center text-gray-1">
Enter any nostr identifier (npub, nevent, nprofile, note or user@domain.tld), or click on the
camera icon to scan with your device's camera instead.
</div>
{#if status === "loading"}
<Spinner>Loading your camera...</Spinner>
{/if}

View File

@ -1,8 +1,16 @@
<script>
import Heading from "src/partials/Heading.svelte"
import Content from "src/partials/Content.svelte"
import PersonSearch from "src/views/person/PersonSearch.svelte"
</script>
<Content>
<div class="flex flex-col items-center justify-center">
<Heading>Profile Search</Heading>
<p>
Search for people on Nostr. For now, only profiles that have already been loaded will appear
in search results.
</p>
</div>
<PersonSearch />
</Content>

View File

@ -35,7 +35,7 @@
<Content>
<div class="mb-4 flex flex-col items-center justify-center">
<Heading>App Settings</Heading>
<p>Tweak Coracle to work the way you want it to.</p>
<p>Make Coracle work the way you want it to.</p>
</div>
<div class="flex w-full flex-col gap-8">
<div class="flex flex-col gap-1">

View File

@ -4,79 +4,45 @@
import Content from "src/partials/Content.svelte"
import RelayCard from "src/views/relays/RelayCard.svelte"
import {copyToClipboard} from "src/util/html"
import {warn} from "src/util/logger"
import {onMount} from "svelte"
import {fly} from "svelte/transition"
export let person
// local items
let nip05ProfileData = null
let nip05QueryEndpoint = null
let nProfile = null
let nprofile = null
let npub = nip19.npubEncode(person.pubkey)
// local state
let loaded = false
onMount(() => {
if (person && person.verified_as) {
// get target URI
nip05QueryEndpoint = getNip05QueryEndpoint(person.verified_as)
// calculate nProfile from NIP05 data, if available
nProfile = nip19.nprofileEncode({
onMount(async () => {
if (person.verified_as) {
nprofile = nip19.nprofileEncode({
pubkey: person.pubkey,
relays: person.relays,
})
// fetch data
nip05
.queryProfile(person.verified_as)
.then(data => {
nip05ProfileData = data
try {
nip05ProfileData = await nip05.queryProfile(person.verified_as)
} catch (e) {
// Pass
}
// recalculate nprofile using NIP05 relay data, if specified.
// In theory, those *should* be the user's prefered relay set.
if (nip05ProfileData?.relays?.length) {
nProfile = nip19.nprofileEncode({
pubkey: person.pubkey,
relays: nip05ProfileData.relays,
})
}
// recalculate nprofile using NIP05 relay data, if specified.
// In theory, those *should* be the user's prefered relay set.
if (nip05ProfileData?.relays?.length) {
nprofile = nip19.nprofileEncode({
pubkey: person.pubkey,
relays: nip05ProfileData.relays,
})
.catch(err => {
warn("NIP05 profile retrieval failed")
})
.finally(() => {
loaded = true
})
} else {
loaded = true
}
}
loaded = true
})
// Construct NIP05 URL from identifier.
function getNip05QueryEndpoint(identifier) {
if (!identifier) return null
let name, domain
if (identifier.match(/^.*@.*$/)) {
;[name, domain] = identifier.split("@")
} else {
// In case of no name (domain-only), mimick the reasonable
// (but somewhat questionable) behaviour of nostr-tools/nip05,
// which defaults the name value
;[name, domain] = ["_", identifier]
}
return `https://${domain}/.well-known/nostr.json?name=${name}`
}
// helper: clipboard & toast
function copy(text) {
const copy = (label, text) => {
copyToClipboard(text)
toast.show("info", `Copied.`)
toast.show("info", `${label} copied to clipboard!`)
}
</script>
@ -86,7 +52,9 @@
<div>
<div class="mb-1 text-lg">Public Key (Hex)</div>
<div class="font-mono text-sm">
<button class="fa-solid fa-copy cursor-pointer" on:click={() => copy(person.pubkey)} />
<button
class="fa-solid fa-copy cursor-pointer"
on:click={() => copy("Public key", person.pubkey)} />
{person.pubkey}
</div>
</div>
@ -94,17 +62,21 @@
<div class="mb-1 text-lg">Public Key (npub)</div>
<div class="font-mono text-sm">
{#if npub}
<button class="fa-solid fa-copy cursor-pointer" on:click={() => copy(npub)} />
<button
class="fa-solid fa-copy cursor-pointer"
on:click={() => copy("Public key", npub)} />
{/if}
{npub}
</div>
</div>
{#if nProfile}
<div>
<div class="mb-1 text-lg">nprofile</div>
{#if nprofile}
<div class="flex flex-col gap-2">
<div class="text-lg">Profile Link</div>
<div class="break-all font-mono text-sm">
<button class="fa-solid fa-copy inline cursor-pointer" on:click={() => copy(nProfile)} />
{nProfile}
<button
class="fa-solid fa-copy inline cursor-pointer"
on:click={() => copy("Profile", nprofile)} />
{nprofile}
</div>
</div>
{/if}
@ -118,23 +90,11 @@
{#if person.verified_as}
<button
class="fa-solid fa-copy inline cursor-pointer"
on:click={() => copy(person.verified_as)} />
on:click={() => copy("NIP05 Identifier", person.verified_as)} />
{/if}
{person.verified_as || "?"}
</div>
</div>
<div>
<div class="mb-1 text-lg">NIP05 Validation Endpoint</div>
<div class="font-mono text-sm">
{#if nip05QueryEndpoint}
<button
class="fa-solid fa-copy inline cursor-pointer"
on:click={() => copy(nip05QueryEndpoint)} />
{/if}
{nip05QueryEndpoint || "?"}
</div>
</div>
{#if nip05ProfileData}
<div>
<div class="mb-2 text-lg">NIP05 Relay Configuration</div>
@ -142,14 +102,13 @@
<p class="mb-4 text-sm text-gray-1">
These relays are advertised by the NIP05 identifier's validation endpoint.
</p>
<div class="grid grid-cols-1 gap-4">
{#each nip05ProfileData?.relays as url}
<RelayCard relay={{url}} />
{/each}
</div>
{:else}
<p class="mb-4 text-sm text-gray-1">
<p class="mb-4 text-sm">
<i class="fa-solid fa-info-circle" />
No relays are advertised by the NIP05 identifier's validation endpoint.
</p>