Clean up previews

This commit is contained in:
Jonathan Staab 2022-12-06 21:55:04 -08:00
parent 849181f795
commit 8d033ea6a4
6 changed files with 57 additions and 50 deletions

View File

@ -1,5 +1,7 @@
Bugs
- [ ] Permalink note detail (share/permalink button?)
- [ ] Back button no longer works if a modal is closed normally
- [ ] Prevent tabs from re-mounting (or at least re- animating)
- [ ] Go "back" after adding a note
- [ ] uniq and sortBy are sprinkled all over the place, figure out a better solution
@ -10,7 +12,7 @@ Features
- [x] Chat
- [x] Threads/social
- [x] Search
- [ ] Permalink note detail (share/permalink button?)
- [ ] Mentions
- [ ] Add "view thread" page that recurs more deeply
- [ ] Fix replies - notes may only include a "root" in its tags
- [x] Link previews

View File

@ -1,12 +1,12 @@
<script>
import cx from 'classnames'
import {find, last, uniqBy, prop, whereEq} from 'ramda'
import {find, uniqBy, prop, whereEq} from 'ramda'
import {onMount} from 'svelte'
import {fly, slide} from 'svelte/transition'
import {navigate} from 'svelte-routing'
import {LinkPreview} from 'svelte-link-preview'
import {ellipsize, first} from 'hurdak/src/core'
import {ellipsize} from 'hurdak/src/core'
import {hasParent, toHtml, findLink} from 'src/util/html'
import Preview from 'src/partials/Preview.svelte'
import Anchor from 'src/partials/Anchor.svelte'
import {dispatch} from "src/state/dispatch"
import {findReplyTo} from "src/state/nostr"
@ -21,7 +21,7 @@
export let interactive = false
export let invertColors = false
let preview = null
let link = null
let like = null
let flag = null
let reply = null
@ -34,35 +34,9 @@
}
onMount(async () => {
const link = findLink(note.content)
if (link && $settings.showLinkPreviews) {
preview = await getLinkPreview(link)
}
link = $settings.showLinkPreviews ? findLink(note.content) : null
})
const getLinkPreview = async url => {
const res = await fetch(`${$settings.dufflepudUrl}/link/preview`, {
method: 'POST',
body: JSON.stringify({url}),
headers: {
'Content-Type': 'application/json',
},
})
const json = await res.json()
if (!json.title) {
return null
}
return {
...json,
hostname: first(last(url.split('//')).split('/')),
sitename: null,
}
}
const onClick = e => {
if (!['I'].includes(e.target.tagName) && !hasParent('a', e.target)) {
modal.set({note})
@ -148,14 +122,14 @@
</p>
{:else}
<p>
{#if note.content.length > 240 && !showEntire}
{ellipsize(note.content, 240)}
{#if note.content.length > 500 && !showEntire}
{ellipsize(note.content, 500)}
{:else}
{@html toHtml(note.content)}
{/if}
{#if preview}
<div class="mt-2" in:slide on:click={e => e.stopPropagation()}>
<LinkPreview url={preview.url} fetcher={() => preview} />
{#if link}
<div class="mt-2" on:click={e => e.stopPropagation()}>
<Preview endpoint={`${$settings.dufflepudUrl}/link/preview`} url={link} />
</div>
{/if}
</p>

View File

@ -0,0 +1,38 @@
<script>
import {onMount} from 'svelte'
import {slide} from 'svelte/transition'
export let url
export let endpoint
let preview
onMount(async () => {
const res = await fetch(endpoint, {
method: 'POST',
body: JSON.stringify({url}),
headers: {
'Content-Type': 'application/json',
},
})
const json = await res.json()
if (json.title) {
preview = json
}
})
</script>
{#if preview}
<div class="rounded border border-solid border-medium flex flex-col bg-white overflow-hidden" in:slide>
{#if preview.image}
<img src={preview.image} />
<div class="h-px bg-medium" />
{/if}
<div class="px-4 py-2 text-black flex flex-col bg-white">
<strong class="whitespace-nowrap text-ellipsis overflow-hidden">{preview.title}</strong>
<small>{preview.description}</small>
</div>
</div>
{/if}

View File

@ -89,9 +89,9 @@
</div>
</div>
{:else}
<ul class="py-8 flex flex-col gap-2 max-w-xl m-auto">
<ul class="py-4 flex flex-col gap-2 max-w-xl m-auto">
{#each (notes ? $notes : []) as n (n.id)}
<li class="border-l border-solid border-medium">
<li>
<Note interactive note={n} />
{#each n.replies as r (r.id)}
<div class="ml-6 border-l border-solid border-medium">

View File

@ -123,9 +123,9 @@
</div>
</div>
<div class="h-px bg-medium" in:fly={{y: 20, delay: 200}} />
<ul class="flex flex-col -mt-4" in:fly={{y: 20, delay: 400}}>
<ul class="flex flex-col" in:fly={{y: 20, delay: 400}}>
{#each (notes ? $notes : []) as n (n.id)}
<li class="border-l border-solid border-medium pb-2">
<li>
<Note interactive note={n} />
{#each n.replies as r (r.id)}
<div class="ml-6 border-l border-solid border-medium">

View File

@ -140,15 +140,8 @@ export const annotateNotes = async (chunk, {showParents = false} = {}) => {
'#e': pluck('id', chunk.concat(replies)),
})
const repliesById = groupBy(
n => find(t => last(t) === 'reply', n.tags)[1],
replies.filter(n => n.tags.map(last).includes('reply'))
)
const reactionsById = groupBy(
n => find(t => last(t) === 'reply', n.tags)[1],
reactions.filter(n => n.tags.map(last).includes('reply'))
)
const repliesById = groupBy(findReplyTo, replies)
const reactionsById = groupBy(findReplyTo, reactions)
await ensureAccounts(uniq(pluck('pubkey', chunk.concat(replies).concat(reactions))))