mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Clean up previews
This commit is contained in:
parent
849181f795
commit
8d033ea6a4
@ -1,5 +1,7 @@
|
|||||||
Bugs
|
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)
|
- [ ] Prevent tabs from re-mounting (or at least re- animating)
|
||||||
- [ ] Go "back" after adding a note
|
- [ ] Go "back" after adding a note
|
||||||
- [ ] uniq and sortBy are sprinkled all over the place, figure out a better solution
|
- [ ] uniq and sortBy are sprinkled all over the place, figure out a better solution
|
||||||
@ -10,7 +12,7 @@ Features
|
|||||||
- [x] Chat
|
- [x] Chat
|
||||||
- [x] Threads/social
|
- [x] Threads/social
|
||||||
- [x] Search
|
- [x] Search
|
||||||
- [ ] Permalink note detail (share/permalink button?)
|
- [ ] Mentions
|
||||||
- [ ] Add "view thread" page that recurs more deeply
|
- [ ] Add "view thread" page that recurs more deeply
|
||||||
- [ ] Fix replies - notes may only include a "root" in its tags
|
- [ ] Fix replies - notes may only include a "root" in its tags
|
||||||
- [x] Link previews
|
- [x] Link previews
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import cx from 'classnames'
|
import cx from 'classnames'
|
||||||
import {find, last, uniqBy, prop, whereEq} from 'ramda'
|
import {find, uniqBy, prop, whereEq} from 'ramda'
|
||||||
import {onMount} from 'svelte'
|
import {onMount} from 'svelte'
|
||||||
import {fly, slide} from 'svelte/transition'
|
import {fly, slide} from 'svelte/transition'
|
||||||
import {navigate} from 'svelte-routing'
|
import {navigate} from 'svelte-routing'
|
||||||
import {LinkPreview} from 'svelte-link-preview'
|
import {ellipsize} from 'hurdak/src/core'
|
||||||
import {ellipsize, first} from 'hurdak/src/core'
|
|
||||||
import {hasParent, toHtml, findLink} from 'src/util/html'
|
import {hasParent, toHtml, findLink} from 'src/util/html'
|
||||||
|
import Preview from 'src/partials/Preview.svelte'
|
||||||
import Anchor from 'src/partials/Anchor.svelte'
|
import Anchor from 'src/partials/Anchor.svelte'
|
||||||
import {dispatch} from "src/state/dispatch"
|
import {dispatch} from "src/state/dispatch"
|
||||||
import {findReplyTo} from "src/state/nostr"
|
import {findReplyTo} from "src/state/nostr"
|
||||||
@ -21,7 +21,7 @@
|
|||||||
export let interactive = false
|
export let interactive = false
|
||||||
export let invertColors = false
|
export let invertColors = false
|
||||||
|
|
||||||
let preview = null
|
let link = null
|
||||||
let like = null
|
let like = null
|
||||||
let flag = null
|
let flag = null
|
||||||
let reply = null
|
let reply = null
|
||||||
@ -34,35 +34,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const link = findLink(note.content)
|
link = $settings.showLinkPreviews ? findLink(note.content) : null
|
||||||
|
|
||||||
if (link && $settings.showLinkPreviews) {
|
|
||||||
preview = await getLinkPreview(link)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
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 => {
|
const onClick = e => {
|
||||||
if (!['I'].includes(e.target.tagName) && !hasParent('a', e.target)) {
|
if (!['I'].includes(e.target.tagName) && !hasParent('a', e.target)) {
|
||||||
modal.set({note})
|
modal.set({note})
|
||||||
@ -148,14 +122,14 @@
|
|||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p>
|
<p>
|
||||||
{#if note.content.length > 240 && !showEntire}
|
{#if note.content.length > 500 && !showEntire}
|
||||||
{ellipsize(note.content, 240)}
|
{ellipsize(note.content, 500)}
|
||||||
{:else}
|
{:else}
|
||||||
{@html toHtml(note.content)}
|
{@html toHtml(note.content)}
|
||||||
{/if}
|
{/if}
|
||||||
{#if preview}
|
{#if link}
|
||||||
<div class="mt-2" in:slide on:click={e => e.stopPropagation()}>
|
<div class="mt-2" on:click={e => e.stopPropagation()}>
|
||||||
<LinkPreview url={preview.url} fetcher={() => preview} />
|
<Preview endpoint={`${$settings.dufflepudUrl}/link/preview`} url={link} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
|
38
src/partials/Preview.svelte
Normal file
38
src/partials/Preview.svelte
Normal 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}
|
@ -89,9 +89,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{: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)}
|
{#each (notes ? $notes : []) as n (n.id)}
|
||||||
<li class="border-l border-solid border-medium">
|
<li>
|
||||||
<Note interactive note={n} />
|
<Note interactive note={n} />
|
||||||
{#each n.replies as r (r.id)}
|
{#each n.replies as r (r.id)}
|
||||||
<div class="ml-6 border-l border-solid border-medium">
|
<div class="ml-6 border-l border-solid border-medium">
|
||||||
|
@ -123,9 +123,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-px bg-medium" in:fly={{y: 20, delay: 200}} />
|
<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)}
|
{#each (notes ? $notes : []) as n (n.id)}
|
||||||
<li class="border-l border-solid border-medium pb-2">
|
<li>
|
||||||
<Note interactive note={n} />
|
<Note interactive note={n} />
|
||||||
{#each n.replies as r (r.id)}
|
{#each n.replies as r (r.id)}
|
||||||
<div class="ml-6 border-l border-solid border-medium">
|
<div class="ml-6 border-l border-solid border-medium">
|
||||||
|
@ -140,15 +140,8 @@ export const annotateNotes = async (chunk, {showParents = false} = {}) => {
|
|||||||
'#e': pluck('id', chunk.concat(replies)),
|
'#e': pluck('id', chunk.concat(replies)),
|
||||||
})
|
})
|
||||||
|
|
||||||
const repliesById = groupBy(
|
const repliesById = groupBy(findReplyTo, replies)
|
||||||
n => find(t => last(t) === 'reply', n.tags)[1],
|
const reactionsById = groupBy(findReplyTo, reactions)
|
||||||
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'))
|
|
||||||
)
|
|
||||||
|
|
||||||
await ensureAccounts(uniq(pluck('pubkey', chunk.concat(replies).concat(reactions))))
|
await ensureAccounts(uniq(pluck('pubkey', chunk.concat(replies).concat(reactions))))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user