mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Make sharing indicator nicer
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
* Migrate to svelte 5 (fixes some bugs, probably introduces others)
|
* Migrate to svelte 5 (fixes some bugs, probably introduces others)
|
||||||
* Migrate to new welshman editor
|
* Migrate to new welshman editor
|
||||||
* Make reply indicator nicer
|
* Make reply indicator nicer
|
||||||
* (pending) Make share indicator nicer
|
* Make share indicator nicer
|
||||||
* Improve feed loading
|
* Improve feed loading
|
||||||
* (pending) Show marker for last activity in chat
|
* (pending) Show marker for last activity in chat
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
|
||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
import {isMobile, preventDefault} from "@lib/html"
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
@@ -9,10 +8,9 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onSubmit: any
|
onSubmit: any
|
||||||
content?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const {onSubmit, content = ""}: Props = $props()
|
const {onSubmit}: Props = $props()
|
||||||
|
|
||||||
const autofocus = !isMobile
|
const autofocus = !isMobile
|
||||||
|
|
||||||
@@ -36,10 +34,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const editor = makeEditor({autofocus, submit, uploading, aggressive: true})
|
const editor = makeEditor({autofocus, submit, uploading, aggressive: true})
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
editor.chain().setContent(content).run()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
|
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
|
||||||
|
|||||||
@@ -6,18 +6,21 @@
|
|||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Content from "@app/components/Content.svelte"
|
import Content from "@app/components/Content.svelte"
|
||||||
|
|
||||||
interface Props {
|
const {
|
||||||
|
verb,
|
||||||
|
event,
|
||||||
|
clear,
|
||||||
|
}: {
|
||||||
|
verb: string
|
||||||
event: TrustedEvent
|
event: TrustedEvent
|
||||||
clear: () => void
|
clear: () => void
|
||||||
}
|
} = $props()
|
||||||
|
|
||||||
const {event, clear}: Props = $props()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8 text-xs"
|
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8 text-xs"
|
||||||
transition:slide>
|
transition:slide>
|
||||||
<p class="text-primary">Replying to @{displayProfileByPubkey(event.pubkey)}</p>
|
<p class="text-primary">{verb} @{displayProfileByPubkey(event.pubkey)}</p>
|
||||||
{#key event.id}
|
{#key event.id}
|
||||||
<Content {event} hideMedia minLength={100} maxLength={300} expandMode="disabled" />
|
<Content {event} hideMedia minLength={100} maxLength={300} expandMode="disabled" />
|
||||||
{/key}
|
{/key}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type {Snippet} from "svelte"
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {int, nthNe, MINUTE, sortBy, remove} from "@welshman/lib"
|
import {int, nthNe, MINUTE, sortBy, remove} from "@welshman/lib"
|
||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
@@ -28,7 +29,13 @@
|
|||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
import {sendWrapped, prependParent} from "@app/commands"
|
import {sendWrapped, prependParent} from "@app/commands"
|
||||||
|
|
||||||
const {id, info = undefined} = $props()
|
const {
|
||||||
|
id,
|
||||||
|
info,
|
||||||
|
}: {
|
||||||
|
id: string
|
||||||
|
info?: Snippet
|
||||||
|
} = $props()
|
||||||
|
|
||||||
const chat = deriveChat(id)
|
const chat = deriveChat(id)
|
||||||
const pubkeys = splitChatId(id)
|
const pubkeys = splitChatId(id)
|
||||||
@@ -205,7 +212,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{#if parent}
|
{#if parent}
|
||||||
<ChatComposeParent event={parent} clear={clearParent} />
|
<ChatComposeParent event={parent} clear={clearParent} verb="Replying to" />
|
||||||
{/if}
|
{/if}
|
||||||
<ChatCompose bind:this={compose} {onSubmit} />
|
<ChatCompose bind:this={compose} {onSubmit} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -115,6 +115,8 @@
|
|||||||
const hasEllipsis = $derived(shortContent.some(isEllipsis))
|
const hasEllipsis = $derived(shortContent.some(isEllipsis))
|
||||||
const expandInline = $derived(hasEllipsis && expandMode === "inline")
|
const expandInline = $derived(hasEllipsis && expandMode === "inline")
|
||||||
const expandBlock = $derived(hasEllipsis && expandMode === "block")
|
const expandBlock = $derived(hasEllipsis && expandMode === "block")
|
||||||
|
|
||||||
|
$inspect(fullContent)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
@@ -131,8 +133,8 @@
|
|||||||
class="overflow-hidden text-ellipsis break-words"
|
class="overflow-hidden text-ellipsis break-words"
|
||||||
style={expandBlock ? "mask-image: linear-gradient(0deg, transparent 0px, black 100px)" : ""}>
|
style={expandBlock ? "mask-image: linear-gradient(0deg, transparent 0px, black 100px)" : ""}>
|
||||||
{#each shortContent as parsed, i}
|
{#each shortContent as parsed, i}
|
||||||
{#if isNewline(parsed)}
|
{#if isNewline(parsed) && !isBlock(i - 1)}
|
||||||
<ContentNewline value={parsed.value.slice(isBlock(i - 1) ? 1 : 0)} />
|
<ContentNewline value={parsed.value} />
|
||||||
{:else if isTopic(parsed)}
|
{:else if isTopic(parsed)}
|
||||||
<ContentTopic value={parsed.value} />
|
<ContentTopic value={parsed.value} />
|
||||||
{:else if isCode(parsed)}
|
{:else if isCode(parsed)}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {ctx, nthEq} from "@welshman/lib"
|
import {ctx, nthEq} from "@welshman/lib"
|
||||||
import {tracker, repository} from "@welshman/app"
|
import {tracker, repository} from "@welshman/app"
|
||||||
import {Address, DIRECT_MESSAGE, MESSAGE, THREAD} from "@welshman/util"
|
import {Address, DIRECT_MESSAGE, MESSAGE, THREAD, EVENT_TIME} from "@welshman/util"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import NoteCard from "@app/components/NoteCard.svelte"
|
import NoteCard from "@app/components/NoteCard.svelte"
|
||||||
import {deriveEvent, entityLink, ROOM} from "@app/state"
|
import {deriveEvent, entityLink, ROOM} from "@app/state"
|
||||||
import {makeThreadPath, makeRoomPath} from "@app/routes"
|
import {makeThreadPath, makeCalendarPath, makeRoomPath} from "@app/routes"
|
||||||
|
|
||||||
const {value, event, noteContent, relays = [], minimal = false} = $props()
|
const {value, event, noteContent, relays = [], minimal = false} = $props()
|
||||||
|
|
||||||
@@ -70,6 +70,10 @@
|
|||||||
return goto(makeThreadPath(url, $quote.id))
|
return goto(makeThreadPath(url, $quote.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($quote.kind === EVENT_TIME) {
|
||||||
|
return goto(makeCalendarPath(url, $quote.id))
|
||||||
|
}
|
||||||
|
|
||||||
if ($quote.kind === MESSAGE) {
|
if ($quote.kind === MESSAGE) {
|
||||||
return scrollToEvent($quote.id) || openMessage(url, room, $quote.id)
|
return scrollToEvent($quote.id) || openMessage(url, room, $quote.id)
|
||||||
}
|
}
|
||||||
@@ -82,6 +86,10 @@
|
|||||||
return goto(makeThreadPath(url, id))
|
return goto(makeThreadPath(url, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseInt(kind) === EVENT_TIME) {
|
||||||
|
return goto(makeCalendarPath(url, id))
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt(kind) === MESSAGE) {
|
if (parseInt(kind) === MESSAGE) {
|
||||||
return scrollToEvent(id) || openMessage(url, room, id)
|
return scrollToEvent(id) || openMessage(url, room, id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {nip19} from "nostr-tools"
|
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {ctx} from "@welshman/lib"
|
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {toNostrURI} from "@welshman/util"
|
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
@@ -16,13 +13,10 @@
|
|||||||
|
|
||||||
const {url, noun, event}: {url: string; noun: string; event: TrustedEvent} = $props()
|
const {url, noun, event}: {url: string; noun: string; event: TrustedEvent} = $props()
|
||||||
|
|
||||||
const relays = ctx.app.router.Event(event).getUrls()
|
|
||||||
const nevent = nip19.neventEncode({id: event.id, relays})
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
setKey("content", toNostrURI(nevent))
|
setKey("share", event)
|
||||||
goto(makeRoomPath(url, selection), {replaceState: true})
|
goto(makeRoomPath(url, selection), {replaceState: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
const {room = GENERAL} = $page.params
|
const {room = GENERAL} = $page.params
|
||||||
const lastChecked = $checked[$page.url.pathname]
|
const lastChecked = $checked[$page.url.pathname]
|
||||||
const content = popKey<string>("content") || ""
|
|
||||||
const url = decodeRelay($page.params.relay)
|
const url = decodeRelay($page.params.relay)
|
||||||
const filter = {kinds: [MESSAGE], "#h": [room]}
|
const filter = {kinds: [MESSAGE], "#h": [room]}
|
||||||
const relay = deriveRelay(url)
|
const relay = deriveRelay(url)
|
||||||
@@ -78,17 +77,32 @@
|
|||||||
parent = undefined
|
parent = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearShare = () => {
|
||||||
|
share = undefined
|
||||||
|
}
|
||||||
|
|
||||||
const onSubmit = ({content, tags}: EventContent) => {
|
const onSubmit = ({content, tags}: EventContent) => {
|
||||||
tags.push(tagRoom(room, url))
|
tags.push(tagRoom(room, url))
|
||||||
tags.push(PROTECTED)
|
tags.push(PROTECTED)
|
||||||
|
|
||||||
|
let template = {content, tags}
|
||||||
|
|
||||||
|
if (share) {
|
||||||
|
template = prependParent(share, template)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
template = prependParent(parent, template)
|
||||||
|
}
|
||||||
|
|
||||||
publishThunk({
|
publishThunk({
|
||||||
relays: [url],
|
relays: [url],
|
||||||
event: createEvent(MESSAGE, prependParent(parent, {content, tags})),
|
event: createEvent(MESSAGE, template),
|
||||||
delay: $userSettingValues.send_delay,
|
delay: $userSettingValues.send_delay,
|
||||||
})
|
})
|
||||||
|
|
||||||
clearParent()
|
clearParent()
|
||||||
|
clearShare()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onScroll = () => {
|
const onScroll = () => {
|
||||||
@@ -113,6 +127,7 @@
|
|||||||
const scrollToBottom = () => element?.scrollTo({top: 0, behavior: "smooth"})
|
const scrollToBottom = () => element?.scrollTo({top: 0, behavior: "smooth"})
|
||||||
|
|
||||||
let loading = $state(true)
|
let loading = $state(true)
|
||||||
|
let share = $state(popKey<TrustedEvent | undefined>("share"))
|
||||||
let parent: TrustedEvent | undefined = $state()
|
let parent: TrustedEvent | undefined = $state()
|
||||||
let element: HTMLElement | undefined = $state()
|
let element: HTMLElement | undefined = $state()
|
||||||
let newMessages: HTMLElement | undefined = $state()
|
let newMessages: HTMLElement | undefined = $state()
|
||||||
@@ -264,9 +279,12 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="saib">
|
<div class="saib">
|
||||||
{#if parent}
|
{#if parent}
|
||||||
<ChannelComposeParent event={parent} clear={clearParent} />
|
<ChannelComposeParent event={parent} clear={clearParent} verb="Replying to" />
|
||||||
{/if}
|
{/if}
|
||||||
<ChannelCompose bind:this={compose} {content} {onSubmit} />
|
{#if share}
|
||||||
|
<ChannelComposeParent event={share} clear={clearShare} verb="Sharing" />
|
||||||
|
{/if}
|
||||||
|
<ChannelCompose bind:this={compose} {onSubmit} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user