Route and protect space content through toSpace and publishToSpace instead of repeating the NIP-70 and room checks in every form
This commit is contained in:
parent
d67385632b
commit
ba03406795
14 changed files with 109 additions and 193 deletions
|
|
@ -2,8 +2,6 @@
|
||||||
import type {Snippet} from "svelte"
|
import type {Snippet} from "svelte"
|
||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
import {randomId} from "@welshman/lib"
|
import {randomId} from "@welshman/lib"
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {TimeEvent} from "@welshman/domain"
|
import {TimeEvent} from "@welshman/domain"
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
||||||
|
|
@ -18,11 +16,11 @@
|
||||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import DateTimeRangeInput from "@lib/components/DateTimeRangeInput.svelte"
|
import DateTimeRangeInput from "@lib/components/DateTimeRangeInput.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {publishRoomQuote} from "@app/rooms"
|
import {publishToSpace} from "@app/rooms"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
|
|
||||||
type Values = {
|
type Values = {
|
||||||
d: string
|
d: string
|
||||||
|
|
@ -61,8 +59,6 @@
|
||||||
initialValues = draftKey.get()
|
initialValues = draftKey.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldProtect = $relays.hasNip(url, 70)
|
|
||||||
|
|
||||||
const uploading = writable(false)
|
const uploading = writable(false)
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
@ -101,7 +97,6 @@
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const protect = await shouldProtect
|
|
||||||
const eventWriter = writer(TimeEvent)
|
const eventWriter = writer(TimeEvent)
|
||||||
.setIdentifier(d)
|
.setIdentifier(d)
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
|
|
@ -109,17 +104,9 @@
|
||||||
.setStart(start)
|
.setStart(start)
|
||||||
.setEnd(end)
|
.setEnd(end)
|
||||||
.setContent(content)
|
.setContent(content)
|
||||||
.setProtected(protect)
|
|
||||||
.addTags(...ed.storage.nostr.getEditorTags())
|
.addTags(...ed.storage.nostr.getEditorTags())
|
||||||
|
|
||||||
if (h) {
|
const {error} = await publishToSpace(eventWriter, {url, h, shareToChat})
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
} else {
|
|
||||||
eventWriter.forceRoutes(relay(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
const calendarThunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await calendarThunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -127,11 +114,6 @@
|
||||||
|
|
||||||
draftKey?.clear()
|
draftKey?.clear()
|
||||||
history.back()
|
history.back()
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h, parent: calendarThunk.options.event, protect})
|
|
||||||
}
|
|
||||||
|
|
||||||
pushToast({message: "Your event has been saved!"})
|
pushToast({message: "Your event has been saved!"})
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
import type {Snippet} from "svelte"
|
import type {Snippet} from "svelte"
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import {removeUndefined, randomId, uniq, toggle} from "@welshman/lib"
|
import {removeUndefined, randomId, uniq, toggle} from "@welshman/lib"
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {Classified} from "@welshman/domain"
|
import {Classified} from "@welshman/domain"
|
||||||
import {isMobile, preventDefault} from "@lib/html"
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
import {normalizeTopic} from "@lib/util"
|
import {normalizeTopic} from "@lib/util"
|
||||||
|
|
@ -20,9 +18,9 @@
|
||||||
import CurrencyInput from "@app/components/CurrencyInput.svelte"
|
import CurrencyInput from "@app/components/CurrencyInput.svelte"
|
||||||
import TopicMultiSelect from "@app/components/TopicMultiSelect.svelte"
|
import TopicMultiSelect from "@app/components/TopicMultiSelect.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {publishRoomQuote} from "@app/rooms"
|
import {publishToSpace} from "@app/rooms"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
||||||
|
|
@ -100,8 +98,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const protect = await $relays.hasNip(url, 70)
|
|
||||||
|
|
||||||
const eventWriter = writer(Classified)
|
const eventWriter = writer(Classified)
|
||||||
.setIdentifier(d)
|
.setIdentifier(d)
|
||||||
.setContent(content)
|
.setContent(content)
|
||||||
|
|
@ -111,17 +107,9 @@
|
||||||
.setStatus(status)
|
.setStatus(status)
|
||||||
.setTopics(topics)
|
.setTopics(topics)
|
||||||
.setImages(imageUrls)
|
.setImages(imageUrls)
|
||||||
.setProtected(protect)
|
|
||||||
.addTags(...ed.storage.nostr.getEditorTags())
|
.addTags(...ed.storage.nostr.getEditorTags())
|
||||||
|
|
||||||
if (h) {
|
const {error} = await publishToSpace(eventWriter, {url, h, shareToChat})
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
} else {
|
|
||||||
eventWriter.forceRoutes(relay(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
const classifiedThunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await classifiedThunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -129,10 +117,6 @@
|
||||||
|
|
||||||
draftKey?.clear()
|
draftKey?.clear()
|
||||||
history.back()
|
history.back()
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h, parent: classifiedThunk.options.event, protect})
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@
|
||||||
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 EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {relays, thunks, writer} from "@app/core"
|
import {thunks, writer} from "@app/core"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
|
import {toSpace} from "@app/rooms"
|
||||||
import {loadSendDelay} from "@app/settings"
|
import {loadSendDelay} from "@app/settings"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
|
||||||
|
|
@ -41,17 +42,15 @@
|
||||||
// A reply to a room event is a NIP-22 comment, and a reply to a kind 1 note is a NIP-10 note.
|
// A reply to a room event is a NIP-22 comment, and a reply to a kind 1 note is a NIP-10 note.
|
||||||
const renderReply = async (content: string, tags: string[][]) => {
|
const renderReply = async (content: string, tags: string[][]) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
const eventWriter = writer(Comment)
|
const eventWriter = await toSpace(
|
||||||
.setContent(content)
|
writer(Comment)
|
||||||
.addTags(...tags)
|
.setContent(content)
|
||||||
.setRootFromEvent(event)
|
.addTags(...tags)
|
||||||
.setParentFromEvent(parent ?? event)
|
.setRootFromEvent(event)
|
||||||
.setProtected(await $relays.hasNip(url, 70))
|
.setParentFromEvent(parent ?? event),
|
||||||
|
url,
|
||||||
// An untagged comment isn't visible to the group, so the relay neither gates nor deletes it with the room.
|
h,
|
||||||
if (h) {
|
)
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {relays: [url], event: await eventWriter.renderTemplate()}
|
return {relays: [url], event: await eventWriter.renderTemplate()}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import ComposeParent from "@app/components/ComposeParent.svelte"
|
import ComposeParent from "@app/components/ComposeParent.svelte"
|
||||||
import {prependParent} from "@app/rooms"
|
import {prependParent, toSpace} from "@app/rooms"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {relays, thunks, writer} from "@app/core"
|
import {thunks, writer} from "@app/core"
|
||||||
import {loadSendDelay} from "@app/settings"
|
import {loadSendDelay} from "@app/settings"
|
||||||
|
|
||||||
type Values = {
|
type Values = {
|
||||||
|
|
@ -61,17 +61,15 @@
|
||||||
;({content, tags} = await prependParent(parent, {content, tags}, url))
|
;({content, tags} = await prependParent(parent, {content, tags}, url))
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventWriter = writer(Comment)
|
const eventWriter = await toSpace(
|
||||||
.setContent(content)
|
writer(Comment)
|
||||||
.addTags(...tags)
|
.setContent(content)
|
||||||
.setRootFromEvent(event)
|
.addTags(...tags)
|
||||||
.setParentFromEvent(event)
|
.setRootFromEvent(event)
|
||||||
.setProtected(await $relays.hasNip(url, 70))
|
.setParentFromEvent(event),
|
||||||
|
url,
|
||||||
// An untagged comment isn't visible to the group, so the relay neither gates nor deletes it with the room.
|
h,
|
||||||
if (h) {
|
)
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
const thunk = $thunks.publish({
|
const thunk = $thunks.publish({
|
||||||
relays: [url],
|
relays: [url],
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
import {now} from "@welshman/lib"
|
import {now} from "@welshman/lib"
|
||||||
import {relay, toMsats} from "@welshman/util"
|
import {toMsats} from "@welshman/util"
|
||||||
import {ZapGoal} from "@welshman/domain"
|
import {ZapGoal} from "@welshman/domain"
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {isMobile, preventDefault} from "@lib/html"
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
||||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||||
|
|
@ -22,9 +21,9 @@
|
||||||
import Modal from "@lib/components/Modal.svelte"
|
import Modal from "@lib/components/Modal.svelte"
|
||||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {publishRoomQuote} from "@app/rooms"
|
import {publishToSpace} from "@app/rooms"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
||||||
|
|
@ -49,8 +48,6 @@
|
||||||
|
|
||||||
const initialValues = draftKey.get()
|
const initialValues = draftKey.get()
|
||||||
|
|
||||||
const shouldProtect = $relays.hasNip(url, 70)
|
|
||||||
|
|
||||||
const uploading = writable(false)
|
const uploading = writable(false)
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
@ -103,15 +100,12 @@
|
||||||
imageUrl = result?.url
|
imageUrl = result?.url
|
||||||
}
|
}
|
||||||
|
|
||||||
const protect = await shouldProtect
|
|
||||||
const eventWriter = writer(ZapGoal)
|
const eventWriter = writer(ZapGoal)
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setSummary(content)
|
.setSummary(content)
|
||||||
.setAmount(toMsats(amount))
|
.setAmount(toMsats(amount))
|
||||||
.setUrls([url])
|
.setUrls([url])
|
||||||
.setProtected(protect)
|
|
||||||
.addTags(...ed.storage.nostr.getEditorTags())
|
.addTags(...ed.storage.nostr.getEditorTags())
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (imageUrl) {
|
if (imageUrl) {
|
||||||
eventWriter.setImage(imageUrl)
|
eventWriter.setImage(imageUrl)
|
||||||
|
|
@ -121,12 +115,7 @@
|
||||||
eventWriter.setClosedAt(closedAt)
|
eventWriter.setClosedAt(closedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h) {
|
const {error} = await publishToSpace(eventWriter, {url, h, shareToChat})
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
const goalThunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await goalThunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -134,10 +123,6 @@
|
||||||
|
|
||||||
draftKey.clear()
|
draftKey.clear()
|
||||||
history.back()
|
history.back()
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h, parent: goalThunk.options.event, protect})
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {Pin} from "@welshman/domain"
|
import {Pin} from "@welshman/domain"
|
||||||
import {publish} from "@welshman/app"
|
import {publish} from "@welshman/app"
|
||||||
import PinForm, {type PinFormValues} from "@app/components/PinForm.svelte"
|
import PinForm, {type PinFormValues} from "@app/components/PinForm.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {command, writer} from "@app/core"
|
||||||
import {setPinReference} from "@app/pinboards"
|
import {setPinReference} from "@app/pinboards"
|
||||||
|
import {toSpace} from "@app/rooms"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
url: string
|
url: string
|
||||||
|
|
@ -15,11 +15,7 @@
|
||||||
const {url, address, reference}: Props = $props()
|
const {url, address, reference}: Props = $props()
|
||||||
|
|
||||||
const submit = async ({title, topics, value, content}: PinFormValues) => {
|
const submit = async ({title, topics, value, content}: PinFormValues) => {
|
||||||
const eventWriter = writer(Pin)
|
const eventWriter = await toSpace(writer(Pin).setIdentifier().addBoard(address), url)
|
||||||
.setIdentifier()
|
|
||||||
.addBoard(address)
|
|
||||||
.setProtected(await $relays.hasNip(url, 70))
|
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (!setPinReference(eventWriter, value)) {
|
if (!setPinReference(eventWriter, value)) {
|
||||||
return "Please enter a valid URL or nostr link."
|
return "Please enter a valid URL or nostr link."
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {Pin} from "@welshman/domain"
|
import {Pin} from "@welshman/domain"
|
||||||
import {publish} from "@welshman/app"
|
import {publish} from "@welshman/app"
|
||||||
import type {PinReader} from "@welshman/domain"
|
import type {PinReader} from "@welshman/domain"
|
||||||
import PinForm, {type PinFormValues} from "@app/components/PinForm.svelte"
|
import PinForm, {type PinFormValues} from "@app/components/PinForm.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {command, writer} from "@app/core"
|
||||||
import {pinToReference, setPinReference} from "@app/pinboards"
|
import {pinToReference, setPinReference} from "@app/pinboards"
|
||||||
|
import {toSpace} from "@app/rooms"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
url: string
|
url: string
|
||||||
|
|
@ -15,9 +15,7 @@
|
||||||
const {url, pin}: Props = $props()
|
const {url, pin}: Props = $props()
|
||||||
|
|
||||||
const submit = async ({title, topics, value, content}: PinFormValues) => {
|
const submit = async ({title, topics, value, content}: PinFormValues) => {
|
||||||
const eventWriter = writer(Pin, pin)
|
const eventWriter = await toSpace(writer(Pin, pin), url)
|
||||||
.setProtected(await $relays.hasNip(url, 70))
|
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (!setPinReference(eventWriter, value)) {
|
if (!setPinReference(eventWriter, value)) {
|
||||||
return "Please enter a valid URL or nostr link."
|
return "Please enter a valid URL or nostr link."
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {navigate} from "@app/modal"
|
import {navigate} from "@app/modal"
|
||||||
import {getAddress, relay} from "@welshman/util"
|
import {getAddress} from "@welshman/util"
|
||||||
import {publish} from "@welshman/app"
|
import {publish} from "@welshman/app"
|
||||||
import {Pinboard} from "@welshman/domain"
|
import {Pinboard} from "@welshman/domain"
|
||||||
import type {PinboardReader} from "@welshman/domain"
|
import type {PinboardReader} from "@welshman/domain"
|
||||||
|
|
@ -16,7 +16,8 @@
|
||||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import RelayName from "@app/components/RelayName.svelte"
|
import RelayName from "@app/components/RelayName.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {command, writer} from "@app/core"
|
||||||
|
import {toSpace} from "@app/rooms"
|
||||||
import {makeLibraryPath} from "@app/routes"
|
import {makeLibraryPath} from "@app/routes"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
|
||||||
|
|
@ -33,11 +34,10 @@
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const eventWriter = writer(Pinboard, board)
|
const eventWriter = await toSpace(
|
||||||
.setTitle(title)
|
writer(Pinboard, board).setTitle(title).setDescription(description),
|
||||||
.setDescription(description)
|
url,
|
||||||
.setProtected(await $relays.hasNip(url, 70))
|
)
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (!board) {
|
if (!board) {
|
||||||
eventWriter.setIdentifier().setCollaborative(true)
|
eventWriter.setIdentifier().setCollaborative(true)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {insertAt, now, randomId, removeAt, removeUndefined, spec} from "@welshman/lib"
|
import {insertAt, now, randomId, removeAt, removeUndefined, spec} from "@welshman/lib"
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {Poll} from "@welshman/domain"
|
import {Poll} from "@welshman/domain"
|
||||||
import type {PollType} from "@welshman/domain"
|
import type {PollType} from "@welshman/domain"
|
||||||
import {isMobile, preventDefault} from "@lib/html"
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
|
|
@ -21,9 +19,9 @@
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import Modal from "@lib/components/Modal.svelte"
|
import Modal from "@lib/components/Modal.svelte"
|
||||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {publishRoomQuote} from "@app/rooms"
|
import {publishToSpace} from "@app/rooms"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
|
|
||||||
type Option = {
|
type Option = {
|
||||||
|
|
@ -123,12 +121,7 @@
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const protect = await $relays.hasNip(url, 70)
|
const eventWriter = writer(Poll).setTitle(title.trim()).setPollType(pollType).setUrls([url])
|
||||||
const eventWriter = writer(Poll)
|
|
||||||
.setTitle(title.trim())
|
|
||||||
.setPollType(pollType)
|
|
||||||
.setUrls([url])
|
|
||||||
.setProtected(protect)
|
|
||||||
|
|
||||||
for (const option of nonEmptyOptions) {
|
for (const option of nonEmptyOptions) {
|
||||||
eventWriter.addOption(option)
|
eventWriter.addOption(option)
|
||||||
|
|
@ -138,14 +131,7 @@
|
||||||
eventWriter.setEndsAt(endsAt)
|
eventWriter.setEndsAt(endsAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h) {
|
const {error} = await publishToSpace(eventWriter, {url, h, shareToChat})
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
} else {
|
|
||||||
eventWriter.forceRoutes(relay(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
const pollThunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await pollThunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -153,10 +139,6 @@
|
||||||
|
|
||||||
draftKey.clear()
|
draftKey.clear()
|
||||||
history.back()
|
history.back()
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h, parent: pollThunk.options.event, protect})
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
import {now, ifLet, ago, spec, MINUTE} from "@welshman/lib"
|
import {now, ifLet, ago, spec, MINUTE} from "@welshman/lib"
|
||||||
import type {Maybe} from "@welshman/lib"
|
import type {Maybe} from "@welshman/lib"
|
||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {relay, stamp, MESSAGE, RELAY_ADD_MEMBER, ROOM_ADD_MEMBER} from "@welshman/util"
|
import {stamp, MESSAGE, RELAY_ADD_MEMBER, ROOM_ADD_MEMBER} from "@welshman/util"
|
||||||
import {Message} from "@welshman/domain"
|
import {Message} from "@welshman/domain"
|
||||||
import {MembershipStatus} from "@welshman/app"
|
import {MembershipStatus} from "@welshman/app"
|
||||||
import AltArrowDown from "@assets/icons/alt-arrow-down.svg?dataurl"
|
import AltArrowDown from "@assets/icons/alt-arrow-down.svg?dataurl"
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
getRoomType,
|
getRoomType,
|
||||||
groupRoomMessages,
|
groupRoomMessages,
|
||||||
prependParent,
|
prependParent,
|
||||||
|
toSpace,
|
||||||
} from "@app/rooms"
|
} from "@app/rooms"
|
||||||
import {loadSendDelay} from "@app/settings"
|
import {loadSendDelay} from "@app/settings"
|
||||||
import {isFeedLoading, makeFeed, makeFeedContext, makeScrollLoader} from "@app/feeds"
|
import {isFeedLoading, makeFeed, makeFeedContext, makeScrollLoader} from "@app/feeds"
|
||||||
|
|
@ -174,14 +175,14 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const protect = await shouldProtect
|
|
||||||
|
|
||||||
if (eventToEdit) {
|
if (eventToEdit) {
|
||||||
// Don't do anything if message hasn't changed
|
// Don't do anything if message hasn't changed
|
||||||
if (eventToEdit.content === content) {
|
if (eventToEdit.content === content) {
|
||||||
return clearEventToEdit()
|
return clearEventToEdit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const protect = await shouldProtect
|
||||||
|
|
||||||
// Delete the previous message, to be republished below with the same timestamp
|
// Delete the previous message, to be republished below with the same timestamp
|
||||||
const command = await $deletes.deleteEvent($state.snapshot(eventToEdit), w =>
|
const command = await $deletes.deleteEvent($state.snapshot(eventToEdit), w =>
|
||||||
w.setProtected(protect),
|
w.setProtected(protect),
|
||||||
|
|
@ -195,16 +196,13 @@
|
||||||
;({content, tags} = await prependParent(sharedEvent, {content, tags}, url))
|
;({content, tags} = await prependParent(sharedEvent, {content, tags}, url))
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventWriter = writer(Message)
|
const eventWriter = await toSpace(
|
||||||
.setContent(content)
|
writer(Message)
|
||||||
.addTags(...tags)
|
.setContent(content)
|
||||||
.setProtected(protect)
|
.addTags(...tags),
|
||||||
|
url,
|
||||||
if (h) {
|
h,
|
||||||
eventWriter.setRoom(url, h)
|
)
|
||||||
} else {
|
|
||||||
eventWriter.forceRoutes(relay(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
eventWriter.setParent(parent)
|
eventWriter.setParent(parent)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
import {relay} from "@welshman/util"
|
|
||||||
import {Thread} from "@welshman/domain"
|
import {Thread} from "@welshman/domain"
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {isMobile, preventDefault} from "@lib/html"
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
||||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||||
|
|
@ -17,10 +15,10 @@
|
||||||
import Modal from "@lib/components/Modal.svelte"
|
import Modal from "@lib/components/Modal.svelte"
|
||||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {displayRoom, publishRoomQuote} from "@app/rooms"
|
import {displayRoom, publishToSpace} from "@app/rooms"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
|
||||||
type Values = {
|
type Values = {
|
||||||
|
|
@ -39,7 +37,6 @@
|
||||||
const {url, h, shareToChat = false, initialValues}: Props = $props()
|
const {url, h, shareToChat = false, initialValues}: Props = $props()
|
||||||
const draftKey = new DraftKey<Values>(`thread:${url}:${h ?? ""}`)
|
const draftKey = new DraftKey<Values>(`thread:${url}:${h ?? ""}`)
|
||||||
const draft = draftKey.get()
|
const draft = draftKey.get()
|
||||||
const shouldProtect = $relays.hasNip(url, 70)
|
|
||||||
const room = h ?? initialValues?.h ?? draft?.h ?? ""
|
const room = h ?? initialValues?.h ?? draft?.h ?? ""
|
||||||
|
|
||||||
const uploading = writable(false)
|
const uploading = writable(false)
|
||||||
|
|
@ -73,20 +70,12 @@
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const protect = await shouldProtect
|
|
||||||
const eventWriter = writer(Thread)
|
const eventWriter = writer(Thread)
|
||||||
.setContent(content)
|
.setContent(content)
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setProtected(protect)
|
|
||||||
.addTags(...ed.storage.nostr.getEditorTags())
|
.addTags(...ed.storage.nostr.getEditorTags())
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (room) {
|
const {error} = await publishToSpace(eventWriter, {url, h: room, shareToChat})
|
||||||
eventWriter.setRoom(url, room)
|
|
||||||
}
|
|
||||||
|
|
||||||
const thunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await thunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -94,10 +83,6 @@
|
||||||
|
|
||||||
draftKey.clear()
|
draftKey.clear()
|
||||||
history.back()
|
history.back()
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h: room, parent: thunk.options.event, protect})
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import {derived} from "svelte/store"
|
import {derived} from "svelte/store"
|
||||||
import {APP_DATA, relay, sortEventsDesc, tagSpec, tagValues} from "@welshman/util"
|
import {APP_DATA, sortEventsDesc, tagSpec, tagValues} from "@welshman/util"
|
||||||
import {AppData} from "@welshman/domain"
|
import {AppData} from "@welshman/domain"
|
||||||
import {Relays, publish} from "@welshman/app"
|
import {Relays, publish} from "@welshman/app"
|
||||||
import {command, fromApp, relays, writer} from "@app/core"
|
import {command, fromApp, writer} from "@app/core"
|
||||||
import {deriveEventsForUrl} from "@app/repository"
|
import {deriveEventsForUrl} from "@app/repository"
|
||||||
|
import {toSpace} from "@app/rooms"
|
||||||
|
|
||||||
// NIP-78 app data from the pubkey the space's NIP-11 names, one ["content", <value>] tag per entry.
|
// NIP-78 app data from the pubkey the space's NIP-11 names, one ["content", <value>] tag per entry.
|
||||||
export const FEATURED_CONTENT_D = "flotilla/featured-content"
|
export const FEATURED_CONTENT_D = "flotilla/featured-content"
|
||||||
|
|
@ -29,9 +30,7 @@ export const setFeaturedContent = async (url: string, content: string[]) => {
|
||||||
|
|
||||||
const eventWriter = writer(AppData)
|
const eventWriter = writer(AppData)
|
||||||
.setIdentifier(FEATURED_CONTENT_D)
|
.setIdentifier(FEATURED_CONTENT_D)
|
||||||
.setProtected(await relays.get().hasNip(url, 70))
|
|
||||||
.forceRoutes(relay(url))
|
|
||||||
.addTags(...tags)
|
.addTags(...tags)
|
||||||
|
|
||||||
return command(eventWriter).then(publish)
|
return command(await toSpace(eventWriter, url)).then(publish)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,12 @@ import {
|
||||||
} from "@welshman/util"
|
} from "@welshman/util"
|
||||||
import type {EventContent, TrustedEvent} from "@welshman/util"
|
import type {EventContent, TrustedEvent} from "@welshman/util"
|
||||||
import {Message} from "@welshman/domain"
|
import {Message} from "@welshman/domain"
|
||||||
|
import type {BaseEventReader, EventWriter} from "@welshman/domain"
|
||||||
import {MembershipStatus, RoomLists, makeRoomKey, createSearch, publish} from "@welshman/app"
|
import {MembershipStatus, RoomLists, makeRoomKey, createSearch, publish} from "@welshman/app"
|
||||||
import type {Room, RoomMeta} from "@welshman/app"
|
import type {Room, RoomMeta} from "@welshman/app"
|
||||||
import {
|
import {
|
||||||
deriveUserItem,
|
deriveUserItem,
|
||||||
|
command,
|
||||||
relayManagement,
|
relayManagement,
|
||||||
relayMemberLists,
|
relayMemberLists,
|
||||||
roomLists,
|
roomLists,
|
||||||
|
|
@ -101,20 +103,12 @@ export const prependParent = async (
|
||||||
return {content, tags}
|
return {content, tags}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const publishRoomQuote = async ({
|
export const toSpace = async <W extends EventWriter<BaseEventReader>>(
|
||||||
url,
|
eventWriter: W,
|
||||||
h,
|
url: string,
|
||||||
parent,
|
h?: string,
|
||||||
protect,
|
) => {
|
||||||
delay,
|
eventWriter.setProtected(await relays.get().hasNip(url, 70))
|
||||||
}: {
|
|
||||||
url: string
|
|
||||||
h?: string
|
|
||||||
parent: TrustedEvent
|
|
||||||
protect: boolean
|
|
||||||
delay?: number
|
|
||||||
}) => {
|
|
||||||
const eventWriter = writer(Message).setParent(parent).setProtected(protect)
|
|
||||||
|
|
||||||
if (h) {
|
if (h) {
|
||||||
eventWriter.setRoom(url, h)
|
eventWriter.setRoom(url, h)
|
||||||
|
|
@ -122,6 +116,22 @@ export const publishRoomQuote = async ({
|
||||||
eventWriter.forceRoutes(relay(url))
|
eventWriter.forceRoutes(relay(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return eventWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
export const publishRoomQuote = async ({
|
||||||
|
url,
|
||||||
|
h,
|
||||||
|
parent,
|
||||||
|
delay,
|
||||||
|
}: {
|
||||||
|
url: string
|
||||||
|
h?: string
|
||||||
|
parent: TrustedEvent
|
||||||
|
delay?: number
|
||||||
|
}) => {
|
||||||
|
const eventWriter = await toSpace(writer(Message).setParent(parent), url, h)
|
||||||
|
|
||||||
return thunks.get().publish({
|
return thunks.get().publish({
|
||||||
relays: [url],
|
relays: [url],
|
||||||
event: await eventWriter.renderTemplate(),
|
event: await eventWriter.renderTemplate(),
|
||||||
|
|
@ -129,6 +139,20 @@ export const publishRoomQuote = async ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const publishToSpace = async (
|
||||||
|
eventWriter: EventWriter<BaseEventReader>,
|
||||||
|
{url, h, shareToChat}: {url: string; h?: string; shareToChat?: boolean},
|
||||||
|
) => {
|
||||||
|
const thunk = await command(await toSpace(eventWriter, url, h)).then(publish)
|
||||||
|
const error = await thunk.waitForError()
|
||||||
|
|
||||||
|
if (shareToChat && !error) {
|
||||||
|
publishRoomQuote({url, h, parent: thunk.options.event})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {thunk, error}
|
||||||
|
}
|
||||||
|
|
||||||
// User
|
// User
|
||||||
|
|
||||||
export const userRoomList = deriveUserItem(RoomLists)
|
export const userRoomList = deriveUserItem(RoomLists)
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {now, randomId} from "@welshman/lib"
|
import {now, randomId} from "@welshman/lib"
|
||||||
import {getAddress, relay} from "@welshman/util"
|
import {getAddress} from "@welshman/util"
|
||||||
import {Article} from "@welshman/domain"
|
import {Article} from "@welshman/domain"
|
||||||
import {publish} from "@welshman/app"
|
|
||||||
import {isMobile} from "@lib/html"
|
import {isMobile} from "@lib/html"
|
||||||
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
||||||
import DocumentText from "@assets/icons/document-text.svg?dataurl"
|
import DocumentText from "@assets/icons/document-text.svg?dataurl"
|
||||||
|
|
@ -20,11 +19,11 @@
|
||||||
import SpaceBar from "@app/components/SpaceBar.svelte"
|
import SpaceBar from "@app/components/SpaceBar.svelte"
|
||||||
import TopicMultiSelect from "@app/components/TopicMultiSelect.svelte"
|
import TopicMultiSelect from "@app/components/TopicMultiSelect.svelte"
|
||||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
import {command, relays, writer} from "@app/core"
|
import {writer} from "@app/core"
|
||||||
import {DraftKey} from "@app/drafts"
|
import {DraftKey} from "@app/drafts"
|
||||||
import {makeEditor} from "@app/editor"
|
import {makeEditor} from "@app/editor"
|
||||||
import {decodeRelay} from "@app/relays"
|
import {decodeRelay} from "@app/relays"
|
||||||
import {publishRoomQuote} from "@app/rooms"
|
import {publishToSpace} from "@app/rooms"
|
||||||
import {makeArticlePath} from "@app/routes"
|
import {makeArticlePath} from "@app/routes"
|
||||||
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
import {compressFileForUpload, uploadFile} from "@app/uploads"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
|
@ -48,7 +47,6 @@
|
||||||
|
|
||||||
const draftKey = new DraftKey<Values>(`article:${url}:${h ?? ""}`)
|
const draftKey = new DraftKey<Values>(`article:${url}:${h ?? ""}`)
|
||||||
const initialValues = draftKey.get()
|
const initialValues = draftKey.get()
|
||||||
const shouldProtect = $relays.hasNip(url, 70)
|
|
||||||
const coverInputId = randomId()
|
const coverInputId = randomId()
|
||||||
|
|
||||||
const uploading = writable(false)
|
const uploading = writable(false)
|
||||||
|
|
@ -114,16 +112,13 @@
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const protect = await shouldProtect
|
|
||||||
const eventWriter = writer(Article)
|
const eventWriter = writer(Article)
|
||||||
.setIdentifier(d)
|
.setIdentifier(d)
|
||||||
.setContent(content)
|
.setContent(content)
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setTopics(topics)
|
.setTopics(topics)
|
||||||
.setPublishedAt(now())
|
.setPublishedAt(now())
|
||||||
.setProtected(protect)
|
|
||||||
.addTags(...ed.storage.nostr.getEditorTags())
|
.addTags(...ed.storage.nostr.getEditorTags())
|
||||||
.forceRoutes(relay(url))
|
|
||||||
|
|
||||||
if (summary) {
|
if (summary) {
|
||||||
eventWriter.setSummary(summary)
|
eventWriter.setSummary(summary)
|
||||||
|
|
@ -133,12 +128,7 @@
|
||||||
eventWriter.setImage(image)
|
eventWriter.setImage(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h) {
|
const {thunk, error} = await publishToSpace(eventWriter, {url, h, shareToChat})
|
||||||
eventWriter.setRoom(url, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
const thunk = await command(eventWriter).then(publish)
|
|
||||||
const error = await thunk.waitForError()
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return pushToast({theme: "error", message: error})
|
return pushToast({theme: "error", message: error})
|
||||||
|
|
@ -146,10 +136,6 @@
|
||||||
|
|
||||||
draftKey.clear()
|
draftKey.clear()
|
||||||
goto(makeArticlePath(url, getAddress(thunk.options.event)))
|
goto(makeArticlePath(url, getAddress(thunk.options.event)))
|
||||||
|
|
||||||
if (shareToChat) {
|
|
||||||
publishRoomQuote({url, h, parent: thunk.options.event, protect})
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue