mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-19 19:46:42 +00:00
Open person in modal all the time, add close all button to modal
This commit is contained in:
parent
74ebd6aebf
commit
001200da49
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
# 0.2.28
|
||||||
|
|
||||||
|
- [x] Add basic naddr support
|
||||||
|
- [x] Add scroll to top button, and scroll to top on navigate
|
||||||
|
- [x] Add close all button to modal, open person in modal more often
|
||||||
|
|
||||||
# 0.2.27
|
# 0.2.27
|
||||||
|
|
||||||
- [x] Fix mention notifications
|
- [x] Fix mention notifications
|
||||||
|
12
ROADMAP.md
12
ROADMAP.md
@ -1,13 +1,13 @@
|
|||||||
# Current
|
# Current
|
||||||
|
|
||||||
|
- [ ] Relay reviews
|
||||||
|
- New kind, d as url? Combine with labeling?
|
||||||
|
- Show reviews in relay detail rather than events. Warn about events tab
|
||||||
- [ ] Add preview proxy thing
|
- [ ] Add preview proxy thing
|
||||||
- [ ] Open embedded pubkeys and stuff in modals
|
|
||||||
- [ ] Handle embedded naddrs http://localhost:5173/nevent1qqs0sp3dvtvd9t8glg8l4t4lhamvk4092mnqqtcklylwn50l0fxh75qpzemhxue69uhhyetvv9ujumn0wd68ytnzv9hxgcv4y0g
|
|
||||||
- [ ] Add curated relay list, and an easy way to view content on the relays
|
- [ ] Add curated relay list, and an easy way to view content on the relays
|
||||||
- [ ] Pagination is slow. Maybe load with no window first, then add since?
|
- [ ] White-labeled
|
||||||
- [ ] Add coupon code registration for relay
|
- [ ] Add coupon code registration for relay
|
||||||
- [ ] Repurpose chat as groups
|
- [ ] Avoid leaking events from private relays
|
||||||
- [ ] Avoid leaking events from private relays
|
|
||||||
- [ ] Image classification
|
- [ ] Image classification
|
||||||
- https://github.com/bhky/opennsfw2
|
- https://github.com/bhky/opennsfw2
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import {getRelaysForEventParent} from "src/agent/relays"
|
import {getRelaysForEventParent} from "src/agent/relays"
|
||||||
import {getPersonWithFallback} from "src/agent/db"
|
import {getPersonWithFallback} from "src/agent/db"
|
||||||
import {watch} from "src/agent/db"
|
import {watch} from "src/agent/db"
|
||||||
import {routes, goToPerson} from "src/app/state"
|
import {routes} from "src/app/state"
|
||||||
import NoteContent from "src/app/shared/NoteContent.svelte"
|
import NoteContent from "src/app/shared/NoteContent.svelte"
|
||||||
|
|
||||||
export let note
|
export let note
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<Anchor
|
<Anchor
|
||||||
type="unstyled"
|
type="unstyled"
|
||||||
class="flex items-center gap-2 pr-16 text-lg font-bold"
|
class="flex items-center gap-2 pr-16 text-lg font-bold"
|
||||||
on:click={() => goToPerson($author.pubkey)}>
|
on:click={() => modal.push({type: "person/feed", pubkey: $author.pubkey})}>
|
||||||
<span>{displayPerson($author)}</span>
|
<span>{displayPerson($author)}</span>
|
||||||
{#if $author.verified_as}
|
{#if $author.verified_as}
|
||||||
<i class="fa fa-circle-check text-sm text-accent" />
|
<i class="fa fa-circle-check text-sm text-accent" />
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
import user from "src/agent/user"
|
import user from "src/agent/user"
|
||||||
import network from "src/agent/network"
|
import network from "src/agent/network"
|
||||||
import {getPersonWithFallback} from "src/agent/db"
|
import {getPersonWithFallback} from "src/agent/db"
|
||||||
import {goToPerson} from "src/app/state"
|
|
||||||
|
|
||||||
export let note
|
export let note
|
||||||
export let anchorId = null
|
export let anchorId = null
|
||||||
@ -106,6 +105,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openPerson = pubkey => modal.push({type: "person/feed", pubkey})
|
||||||
|
|
||||||
const openQuote = id => {
|
const openQuote = id => {
|
||||||
modal.push({type: "note/detail", note: {id}})
|
modal.push({type: "note/detail", note: {id}})
|
||||||
}
|
}
|
||||||
@ -130,7 +131,7 @@
|
|||||||
</Anchor>
|
</Anchor>
|
||||||
{:else if type.startsWith("nostr:")}
|
{:else if type.startsWith("nostr:")}
|
||||||
{#if showMedia && value.id && isStandalone(i) && value.id !== anchorId}
|
{#if showMedia && value.id && isStandalone(i) && value.id !== anchorId}
|
||||||
<Card interactive invertColors on:click={() => openQuote(value.id)}>
|
<Card interactive invertColors class="my-2" on:click={() => openQuote(value.id)}>
|
||||||
{#await loadQuote(value)}
|
{#await loadQuote(value)}
|
||||||
<Spinner />
|
<Spinner />
|
||||||
{:then quote}
|
{:then quote}
|
||||||
@ -141,7 +142,7 @@
|
|||||||
stopPropagation
|
stopPropagation
|
||||||
type="unstyled"
|
type="unstyled"
|
||||||
class="flex items-center gap-2"
|
class="flex items-center gap-2"
|
||||||
on:click={() => goToPerson(quote.pubkey)}>
|
on:click={() => openPerson(quote.pubkey)}>
|
||||||
<h2 class="text-lg">{displayPerson(person)}</h2>
|
<h2 class="text-lg">{displayPerson(person)}</h2>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</div>
|
</div>
|
||||||
@ -152,8 +153,8 @@
|
|||||||
</p>
|
</p>
|
||||||
{/await}
|
{/await}
|
||||||
</Card>
|
</Card>
|
||||||
{:else if value.pubkey}
|
{:else if type.match(/np(rofile|ub)$/)}
|
||||||
@<Anchor killEvent on:click={() => goToPerson(value.pubkey)}>
|
@<Anchor killEvent on:click={() => openPerson(value.pubkey)}>
|
||||||
{displayPerson(getPersonWithFallback(value.pubkey))}
|
{displayPerson(getPersonWithFallback(value.pubkey))}
|
||||||
</Anchor>
|
</Anchor>
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -27,14 +27,6 @@ export const routes = {
|
|||||||
person: (pubkey, tab = "notes") => `/people/${nip19.npubEncode(pubkey)}/${tab}`,
|
person: (pubkey, tab = "notes") => `/people/${nip19.npubEncode(pubkey)}/${tab}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const goToPerson = pubkey => {
|
|
||||||
if (document.querySelector(".modal-content")) {
|
|
||||||
navigate(routes.person(pubkey))
|
|
||||||
} else {
|
|
||||||
modal.push({type: "person/feed", pubkey})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const addToList = (type, value) => modal.push({type: "list/select", item: {type, value}})
|
export const addToList = (type, value) => modal.push({type: "list/select", item: {type, value}})
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import {warn} from "src/util/logger"
|
import {warn} from "src/util/logger"
|
||||||
import Content from "src/partials/Content.svelte"
|
import Content from "src/partials/Content.svelte"
|
||||||
import NoteDetail from "src/app/views/NoteDetail.svelte"
|
import NoteDetail from "src/app/views/NoteDetail.svelte"
|
||||||
|
import NaddrDetail from "src/app/views/NaddrDetail.svelte"
|
||||||
import PersonDetail from "src/app/views/PersonDetail.svelte"
|
import PersonDetail from "src/app/views/PersonDetail.svelte"
|
||||||
import {sampleRelays} from "src/agent/relays"
|
import {sampleRelays} from "src/agent/relays"
|
||||||
|
|
||||||
@ -17,6 +18,7 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
try {
|
try {
|
||||||
;({type, data} = nip19.decode(entity) as {type: string; data: any})
|
;({type, data} = nip19.decode(entity) as {type: string; data: any})
|
||||||
|
console.log(data)
|
||||||
relays = sampleRelays((data.relays || []).map(objOf("url")))
|
relays = sampleRelays((data.relays || []).map(objOf("url")))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
warn(e)
|
warn(e)
|
||||||
@ -32,6 +34,10 @@
|
|||||||
<Content>
|
<Content>
|
||||||
<NoteDetail note={{id: data}} />
|
<NoteDetail note={{id: data}} />
|
||||||
</Content>
|
</Content>
|
||||||
|
{:else if type === "naddr"}
|
||||||
|
<Content>
|
||||||
|
<NaddrDetail {...data} />
|
||||||
|
</Content>
|
||||||
{:else if type === "nprofile"}
|
{:else if type === "nprofile"}
|
||||||
<PersonDetail npub={nip19.npubEncode(data.pubkey)} {relays} activeTab="notes" />
|
<PersonDetail npub={nip19.npubEncode(data.pubkey)} {relays} activeTab="notes" />
|
||||||
{:else if type === "npub"}
|
{:else if type === "npub"}
|
||||||
|
60
src/app/views/NaddrDetail.svelte
Normal file
60
src/app/views/NaddrDetail.svelte
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<script>
|
||||||
|
import {onMount} from "svelte"
|
||||||
|
import {first, quantify} from "hurdak/lib/hurdak"
|
||||||
|
import {displayPerson} from "src/util/nostr"
|
||||||
|
import {routes} from 'src/app/state'
|
||||||
|
import Content from "src/partials/Content.svelte"
|
||||||
|
import Anchor from "src/partials/Anchor.svelte"
|
||||||
|
import NoteContent from "src/app/shared/NoteContent.svelte"
|
||||||
|
import Spinner from "src/partials/Spinner.svelte"
|
||||||
|
import network from "src/agent/network"
|
||||||
|
import {sampleRelays} from "src/agent/relays"
|
||||||
|
import {getPersonWithFallback} from "src/agent/db"
|
||||||
|
|
||||||
|
export let identifier
|
||||||
|
export let kind
|
||||||
|
export let pubkey
|
||||||
|
export let relays = []
|
||||||
|
|
||||||
|
let note
|
||||||
|
let loading = true
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
note = first(await network.load({
|
||||||
|
relays: sampleRelays(relays),
|
||||||
|
filter: {kinds: [kind], pubkey, '#d': [identifier]},
|
||||||
|
}))
|
||||||
|
|
||||||
|
loading = false
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Content size="lg">
|
||||||
|
<p>
|
||||||
|
This is a kind {kind} event called "{identifier}", published by
|
||||||
|
<Anchor href={routes.person(pubkey)}>@{displayPerson(getPersonWithFallback(pubkey))}</Anchor>.
|
||||||
|
</p>
|
||||||
|
{#if note?.content}
|
||||||
|
<NoteContent showEntire {note} />
|
||||||
|
{/if}
|
||||||
|
{#if note?.tags.length > 1}
|
||||||
|
<p>This note has {quantify(note.tags.length - 1, 'tag')}:</p>
|
||||||
|
<ul class="list-disc list-inside">
|
||||||
|
{#each note.tags as [type, value, ...rest]}
|
||||||
|
{#if type !== "d"}
|
||||||
|
<li>
|
||||||
|
{#if type === "p"}
|
||||||
|
<Anchor href={routes.person(value)}>@{displayPerson(getPersonWithFallback(value))}</Anchor>
|
||||||
|
{:else if type === "e"}
|
||||||
|
<Anchor href={value}>Event {value}</Anchor>
|
||||||
|
{:else}
|
||||||
|
{type}: {value} {rest.length > 0 ? rest.join(', ') : ""}
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{:else if loading}
|
||||||
|
<Spinner />
|
||||||
|
{/if}
|
||||||
|
</Content>
|
@ -10,6 +10,7 @@
|
|||||||
let root, content
|
let root, content
|
||||||
|
|
||||||
const id = randomId()
|
const id = randomId()
|
||||||
|
const {stack} = modal
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (virtual) {
|
if (virtual) {
|
||||||
@ -42,14 +43,23 @@
|
|||||||
class:cursor-pointer={onEscape}
|
class:cursor-pointer={onEscape}
|
||||||
on:click={onEscape}>
|
on:click={onEscape}>
|
||||||
<div class="mt-12 min-h-full">
|
<div class="mt-12 min-h-full">
|
||||||
<div class="pointer-events-none sticky top-0 z-10 flex w-full justify-end p-2">
|
{#if onEscape}
|
||||||
|
<div class="pointer-events-none sticky top-0 z-10 flex w-full flex-col items-end gap-2 p-2">
|
||||||
<div
|
<div
|
||||||
class:opacity-0={!onEscape}
|
class="pointer-events-auto flex h-10 w-10 cursor-pointer items-center justify-center rounded-full
|
||||||
class="pointer-events-auto flex h-10 w-10 cursor-pointer items-center justify-center
|
border border-solid border-accent-light bg-accent text-white transition-colors hover:bg-accent-light">
|
||||||
rounded-full border border-solid border-accent-light bg-accent text-white">
|
|
||||||
<i class="fa fa-times fa-lg" />
|
<i class="fa fa-times fa-lg" />
|
||||||
</div>
|
</div>
|
||||||
|
{#if $stack.length > 1}
|
||||||
|
<div
|
||||||
|
on:click|stopPropagation={() => modal.clear()}
|
||||||
|
class="pointer-events-auto flex h-10 w-10 cursor-pointer items-center justify-center rounded-full
|
||||||
|
border border-solid border-gray-7 bg-gray-6 text-gray-1 transition-colors hover:bg-gray-5">
|
||||||
|
<i class="fa fa-angles-down fa-lg" />
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="absolute mt-12 h-full w-full bg-gray-7" />
|
<div class="absolute mt-12 h-full w-full bg-gray-7" />
|
||||||
<div
|
<div
|
||||||
class="relative h-full w-full cursor-auto border-t border-solid border-gray-6 bg-gray-7 pt-2 pb-10"
|
class="relative h-full w-full cursor-auto border-t border-solid border-gray-6 bg-gray-7 pt-2 pb-10"
|
||||||
|
@ -4,7 +4,7 @@ import type {Writable} from "svelte/store"
|
|||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {writable, get} from "svelte/store"
|
import {writable, get} from "svelte/store"
|
||||||
import {globalHistory} from "svelte-routing/src/history"
|
import {globalHistory} from "svelte-routing/src/history"
|
||||||
import {sleep, shadeColor, synced, WritableList} from "src/util/misc"
|
import {shadeColor, synced, WritableList} from "src/util/misc"
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
|
|
||||||
@ -68,19 +68,18 @@ export const modal = {
|
|||||||
push(data) {
|
push(data) {
|
||||||
modal.stack.update($stack => modal.sync($stack.concat(data)))
|
modal.stack.update($stack => modal.sync($stack.concat(data)))
|
||||||
},
|
},
|
||||||
async pop() {
|
pop() {
|
||||||
modal.stack.update($stack => modal.sync($stack.slice(0, -1)))
|
modal.stack.update($stack => modal.sync($stack.slice(0, -1)))
|
||||||
await sleep(100)
|
|
||||||
},
|
},
|
||||||
async replace(data) {
|
replace(data) {
|
||||||
modal.stack.update($stack => $stack.slice(0, -1).concat(data))
|
modal.stack.update($stack => $stack.slice(0, -1).concat(data))
|
||||||
},
|
},
|
||||||
async clear() {
|
clear() {
|
||||||
const stackSize = (get(modal.stack) as any).length
|
const stackSize = (get(modal.stack) as any).length
|
||||||
|
|
||||||
// Reverse history so the back button doesn't bring our modal back up
|
// Reverse history so the back button doesn't bring our modal back up
|
||||||
for (let i = 0; i < stackSize; i++) {
|
for (let i = 0; i < stackSize; i++) {
|
||||||
await modal.pop()
|
modal.pop()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ export const parseContent = ({content, tags = []}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const parseBech32 = () => {
|
const parseBech32 = () => {
|
||||||
const bech32 = first(text.match(/^(nostr:)?n(event|ote|profile|pub)1[\d\w]+/i))
|
const bech32 = first(text.match(/^(nostr:)?n(event|ote|profile|pub|addr)1[\d\w]+/i))
|
||||||
|
|
||||||
if (bech32) {
|
if (bech32) {
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user