Use lib version of date functions
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
A discord-like nostr client based on the idea of "relays as groups".
|
A discord-like nostr client based on the idea of "relays as groups".
|
||||||
|
|
||||||
If you would like to be interoperable with Flotilla, please check out this draft NIP: https://github.com/coracle-social/nips/blob/relay-chat/xx.md
|
If you would like to be interoperable with Flotilla, please check out this guide: https://habla.news/u/hodlbod@coracle.social/1741286140797
|
||||||
|
|
||||||
# Deploy
|
# Deploy
|
||||||
|
|
||||||
|
|||||||
+1
-27
@@ -2,7 +2,7 @@ import * as nip19 from "nostr-tools/nip19"
|
|||||||
import {get} from "svelte/store"
|
import {get} from "svelte/store"
|
||||||
import {randomId, ifLet, poll, uniq, equals} from "@welshman/lib"
|
import {randomId, ifLet, poll, uniq, equals} from "@welshman/lib"
|
||||||
import type {Feed} from "@welshman/feeds"
|
import type {Feed} from "@welshman/feeds"
|
||||||
import type {TrustedEvent, EventContent, EventTemplate} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {
|
import {
|
||||||
DELETE,
|
DELETE,
|
||||||
REPORT,
|
REPORT,
|
||||||
@@ -34,14 +34,12 @@ import {
|
|||||||
RelayMode,
|
RelayMode,
|
||||||
} from "@welshman/util"
|
} from "@welshman/util"
|
||||||
import {Pool, PublishStatus, AuthStatus, SocketStatus} from "@welshman/net"
|
import {Pool, PublishStatus, AuthStatus, SocketStatus} from "@welshman/net"
|
||||||
import {Nip59, stamp} from "@welshman/signer"
|
|
||||||
import {Router} from "@welshman/router"
|
import {Router} from "@welshman/router"
|
||||||
import {
|
import {
|
||||||
pubkey,
|
pubkey,
|
||||||
signer,
|
signer,
|
||||||
repository,
|
repository,
|
||||||
publishThunk,
|
publishThunk,
|
||||||
MergedThunk,
|
|
||||||
profilesByPubkey,
|
profilesByPubkey,
|
||||||
relaySelectionsByPubkey,
|
relaySelectionsByPubkey,
|
||||||
tagEvent,
|
tagEvent,
|
||||||
@@ -336,30 +334,6 @@ export const attemptRelayAccess = async (url: string, claim = "") => {
|
|||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
|
||||||
export const sendWrapped = async ({
|
|
||||||
template,
|
|
||||||
pubkeys,
|
|
||||||
delay,
|
|
||||||
}: {
|
|
||||||
template: EventTemplate
|
|
||||||
pubkeys: string[]
|
|
||||||
delay?: number
|
|
||||||
}) => {
|
|
||||||
const nip59 = Nip59.fromSigner(signer.get()!)
|
|
||||||
|
|
||||||
return new MergedThunk(
|
|
||||||
await Promise.all(
|
|
||||||
uniq(pubkeys).map(async recipient =>
|
|
||||||
publishThunk({
|
|
||||||
event: await nip59.wrap(recipient, stamp(template)),
|
|
||||||
relays: Router.get().PubkeyInbox(recipient).getUrls(),
|
|
||||||
delay,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeDelete = ({event}: {event: TrustedEvent}) => {
|
export const makeDelete = ({event}: {event: TrustedEvent}) => {
|
||||||
const tags = [["k", String(event.kind)], ...tagEvent(event)]
|
const tags = [["k", String(event.kind)], ...tagEvent(event)]
|
||||||
const groupTag = getTag("h", event.tags)
|
const groupTag = getTag("h", event.tags)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {fromPairs} from "@welshman/lib"
|
import {fromPairs, LOCALE, secondsToDate} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {LOCALE, secondsToDate} from "@welshman/app"
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
event: TrustedEvent
|
event: TrustedEvent
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {fromPairs} from "@welshman/lib"
|
import {
|
||||||
|
fromPairs,
|
||||||
|
formatTimestamp,
|
||||||
|
formatTimestampAsDate,
|
||||||
|
formatTimestampAsTime,
|
||||||
|
} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import {formatTimestamp, formatTimestampAsDate, formatTimestampAsTime} from "@welshman/app"
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
event: TrustedEvent
|
event: TrustedEvent
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {hash, now} from "@welshman/lib"
|
import {hash, now, formatTimestampAsTime, formatTimestampAsDate} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {
|
import {thunks, pubkey, deriveProfile, deriveProfileDisplay} from "@welshman/app"
|
||||||
thunks,
|
|
||||||
pubkey,
|
|
||||||
formatTimestampAsDate,
|
|
||||||
formatTimestampAsTime,
|
|
||||||
deriveProfile,
|
|
||||||
deriveProfileDisplay,
|
|
||||||
} from "@welshman/app"
|
|
||||||
import {isMobile} from "@lib/html"
|
import {isMobile} from "@lib/html"
|
||||||
import TapTarget from "@lib/components/TapTarget.svelte"
|
import TapTarget from "@lib/components/TapTarget.svelte"
|
||||||
import Avatar from "@lib/components/Avatar.svelte"
|
import Avatar from "@lib/components/Avatar.svelte"
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {Snippet} from "svelte"
|
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, formatTimestampAsDate} from "@welshman/lib"
|
||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {createEvent, DIRECT_MESSAGE, INBOX_RELAYS} from "@welshman/util"
|
import {createEvent, DIRECT_MESSAGE, INBOX_RELAYS} from "@welshman/util"
|
||||||
import {
|
import {
|
||||||
pubkey,
|
pubkey,
|
||||||
tagPubkey,
|
tagPubkey,
|
||||||
|
sendWrapped,
|
||||||
loadUsingOutbox,
|
loadUsingOutbox,
|
||||||
formatTimestampAsDate,
|
|
||||||
inboxRelaySelectionsByPubkey,
|
inboxRelaySelectionsByPubkey,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
import ProfileDetail from "@app/components/ProfileDetail.svelte"
|
import ProfileDetail from "@app/components/ProfileDetail.svelte"
|
||||||
import ProfileList from "@app/components/ProfileList.svelte"
|
import ProfileList from "@app/components/ProfileList.svelte"
|
||||||
import ChatMessage from "@app/components/ChatMessage.svelte"
|
import ChatMessage from "@app/components/ChatMessage.svelte"
|
||||||
import ChatCompose from "@app/components/ChannelCompose.svelte"
|
import ChatCompose from "@app/components/ChatCompose.svelte"
|
||||||
import ChatComposeParent from "@app/components/ChannelComposeParent.svelte"
|
import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
|
||||||
import {
|
import {
|
||||||
INDEXER_RELAYS,
|
INDEXER_RELAYS,
|
||||||
userSettingValues,
|
userSettingValues,
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
PLATFORM_NAME,
|
PLATFORM_NAME,
|
||||||
} from "@app/state"
|
} from "@app/state"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
import {sendWrapped, prependParent} from "@app/commands"
|
import {prependParent} from "@app/commands"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string
|
id: string
|
||||||
@@ -137,54 +137,57 @@
|
|||||||
}, 5000)
|
}, 5000)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if others.length > 0}
|
<PageBar>
|
||||||
<PageBar>
|
{#snippet title()}
|
||||||
{#snippet title()}
|
<div class="flex flex-col gap-1 sm:flex-row sm:gap-2">
|
||||||
<div class="flex flex-col gap-1 sm:flex-row sm:gap-2">
|
{#if others.length === 0}
|
||||||
{#if others.length === 1}
|
<div class="row-2">
|
||||||
{@const pubkey = others[0]}
|
<ProfileCircle pubkey={$pubkey!} size={5} />
|
||||||
{@const onClick = () => pushModal(ProfileDetail, {pubkey})}
|
<ProfileName pubkey={$pubkey!} />
|
||||||
<Button onclick={onClick} class="row-2">
|
</div>
|
||||||
<ProfileCircle {pubkey} size={5} />
|
{:else if others.length === 1}
|
||||||
<ProfileName {pubkey} />
|
{@const pubkey = others[0]}
|
||||||
</Button>
|
{@const onClick = () => pushModal(ProfileDetail, {pubkey})}
|
||||||
{:else}
|
<Button onclick={onClick} class="row-2">
|
||||||
<div class="flex items-center gap-2">
|
<ProfileCircle {pubkey} size={5} />
|
||||||
<ProfileCircles pubkeys={others} size={5} />
|
<ProfileName {pubkey} />
|
||||||
<p class="overflow-hidden text-ellipsis whitespace-nowrap">
|
</Button>
|
||||||
<ProfileName pubkey={others[0]} />
|
{:else}
|
||||||
and
|
<div class="flex items-center gap-2">
|
||||||
{#if others.length === 2}
|
<ProfileCircles pubkeys={others} size={5} />
|
||||||
<ProfileName pubkey={others[1]} />
|
<p class="overflow-hidden text-ellipsis whitespace-nowrap">
|
||||||
{:else}
|
<ProfileName pubkey={others[0]} />
|
||||||
{others.length - 1}
|
and
|
||||||
{others.length > 2 ? "others" : "other"}
|
{#if others.length === 2}
|
||||||
{/if}
|
<ProfileName pubkey={others[1]} />
|
||||||
</p>
|
{:else}
|
||||||
</div>
|
{others.length - 1}
|
||||||
{#if others.length > 2}
|
{others.length > 2 ? "others" : "other"}
|
||||||
<Button onclick={showMembers} class="btn btn-link hidden sm:block"
|
{/if}
|
||||||
>Show all members</Button>
|
</p>
|
||||||
{/if}
|
</div>
|
||||||
|
{#if others.length > 2}
|
||||||
|
<Button onclick={showMembers} class="btn btn-link hidden sm:block"
|
||||||
|
>Show all members</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
{/if}
|
||||||
{/snippet}
|
</div>
|
||||||
{#snippet action()}
|
{/snippet}
|
||||||
<div>
|
{#snippet action()}
|
||||||
{#if remove($pubkey, missingInboxes).length > 0}
|
<div>
|
||||||
{@const count = remove($pubkey, missingInboxes).length}
|
{#if remove($pubkey, missingInboxes).length > 0}
|
||||||
{@const label = count > 1 ? "inboxes are" : "inbox is"}
|
{@const count = remove($pubkey, missingInboxes).length}
|
||||||
<div
|
{@const label = count > 1 ? "inboxes are" : "inbox is"}
|
||||||
class="row-2 badge badge-error badge-lg tooltip tooltip-left cursor-pointer"
|
<div
|
||||||
data-tip="{count} {label} not configured.">
|
class="row-2 badge badge-error badge-lg tooltip tooltip-left cursor-pointer"
|
||||||
<Icon icon="danger" />
|
data-tip="{count} {label} not configured.">
|
||||||
{count}
|
<Icon icon="danger" />
|
||||||
</div>
|
{count}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/snippet}
|
</div>
|
||||||
</PageBar>
|
{/snippet}
|
||||||
{/if}
|
</PageBar>
|
||||||
|
|
||||||
<PageContent class="flex flex-col-reverse pt-4">
|
<PageContent class="flex flex-col-reverse pt-4">
|
||||||
<div bind:this={dynamicPadding}></div>
|
<div bind:this={dynamicPadding}></div>
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {writable} from "svelte/store"
|
||||||
|
import type {EventContent} from "@welshman/util"
|
||||||
|
import {isMobile, preventDefault} from "@lib/html"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||||
|
import {makeEditor} from "@app/editor"
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
url?: string
|
||||||
|
onSubmit: (event: EventContent) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const {onSubmit, url}: Props = $props()
|
||||||
|
|
||||||
|
const autofocus = !isMobile
|
||||||
|
|
||||||
|
const uploading = writable(false)
|
||||||
|
|
||||||
|
export const focus = () => editor.then(ed => ed.chain().focus().run())
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
if ($uploading) return
|
||||||
|
|
||||||
|
const ed = await editor
|
||||||
|
const content = ed.getText({blockSeparator: "\n"}).trim()
|
||||||
|
const tags = ed.storage.nostr.getEditorTags()
|
||||||
|
|
||||||
|
if (!content) return
|
||||||
|
|
||||||
|
onSubmit({content, tags})
|
||||||
|
|
||||||
|
ed.chain().clearContent().run()
|
||||||
|
}
|
||||||
|
|
||||||
|
const editor = makeEditor({
|
||||||
|
url,
|
||||||
|
autofocus,
|
||||||
|
submit,
|
||||||
|
uploading,
|
||||||
|
aggressive: true,
|
||||||
|
disableFileUpload: true,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
|
||||||
|
<div class="chat-editor flex-grow overflow-hidden">
|
||||||
|
<EditorContent {editor} />
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
data-tip="{window.navigator.platform.includes('Mac') ? 'cmd' : 'ctrl'}+enter to send"
|
||||||
|
class="center tooltip tooltip-left absolute right-4 h-10 w-10 min-w-10 rounded-full"
|
||||||
|
disabled={$uploading}
|
||||||
|
onclick={submit}>
|
||||||
|
<Icon icon="plain" />
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
|
import {displayProfileByPubkey} from "@welshman/app"
|
||||||
|
import {slide} from "@lib/transition"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import NoteContent from "@app/components/NoteContent.svelte"
|
||||||
|
|
||||||
|
const {
|
||||||
|
verb,
|
||||||
|
event,
|
||||||
|
clear,
|
||||||
|
}: {
|
||||||
|
verb: string
|
||||||
|
event: TrustedEvent
|
||||||
|
clear: () => void
|
||||||
|
} = $props()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8 text-xs"
|
||||||
|
transition:slide>
|
||||||
|
<p class="text-primary">{verb} @{displayProfileByPubkey(event.pubkey)}</p>
|
||||||
|
{#key event.id}
|
||||||
|
<NoteContent
|
||||||
|
{event}
|
||||||
|
hideMediaAtDepth={0}
|
||||||
|
minLength={100}
|
||||||
|
maxLength={300}
|
||||||
|
expandMode="disabled" />
|
||||||
|
{/key}
|
||||||
|
<Button class="absolute right-2 top-2 cursor-pointer" onclick={clear}>
|
||||||
|
<Icon icon="close-circle" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
@@ -1,14 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {type Instance} from "tippy.js"
|
import {type Instance} from "tippy.js"
|
||||||
import {hash} from "@welshman/lib"
|
import {hash, formatTimestampAsTime} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {
|
import {thunks, pubkey, deriveProfile, deriveProfileDisplay, sendWrapped} from "@welshman/app"
|
||||||
thunks,
|
|
||||||
formatTimestampAsTime,
|
|
||||||
pubkey,
|
|
||||||
deriveProfile,
|
|
||||||
deriveProfileDisplay,
|
|
||||||
} from "@welshman/app"
|
|
||||||
import {isMobile} from "@lib/html"
|
import {isMobile} 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"
|
||||||
@@ -22,7 +16,7 @@
|
|||||||
import ChatMessageMenu from "@app/components/ChatMessageMenu.svelte"
|
import ChatMessageMenu from "@app/components/ChatMessageMenu.svelte"
|
||||||
import ChatMessageMenuMobile from "@app/components/ChatMessageMenuMobile.svelte"
|
import ChatMessageMenuMobile from "@app/components/ChatMessageMenuMobile.svelte"
|
||||||
import {colors} from "@app/state"
|
import {colors} from "@app/state"
|
||||||
import {makeDelete, makeReaction, sendWrapped} from "@app/commands"
|
import {makeDelete, makeReaction} from "@app/commands"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {NativeEmoji} from "emoji-picker-element/shared"
|
import type {NativeEmoji} from "emoji-picker-element/shared"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
|
import {sendWrapped} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import EmojiButton from "@lib/components/EmojiButton.svelte"
|
import EmojiButton from "@lib/components/EmojiButton.svelte"
|
||||||
import {makeReaction, sendWrapped} from "@app/commands"
|
import {makeReaction} from "@app/commands"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
event: TrustedEvent
|
event: TrustedEvent
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {NativeEmoji} from "emoji-picker-element/shared"
|
import type {NativeEmoji} from "emoji-picker-element/shared"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
|
import {sendWrapped} from "@welshman/app"
|
||||||
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"
|
||||||
import EmojiPicker from "@lib/components/EmojiPicker.svelte"
|
import EmojiPicker from "@lib/components/EmojiPicker.svelte"
|
||||||
import EventInfo from "@app/components/EventInfo.svelte"
|
import EventInfo from "@app/components/EventInfo.svelte"
|
||||||
import {makeReaction, sendWrapped} from "@app/commands"
|
import {makeReaction} from "@app/commands"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
import {clip} from "@app/toast"
|
import {clip} from "@app/toast"
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {max} from "@welshman/lib"
|
import {max, formatTimestampRelative} from "@welshman/lib"
|
||||||
import {COMMENT} from "@welshman/util"
|
import {COMMENT} from "@welshman/util"
|
||||||
import {load} from "@welshman/net"
|
import {load} from "@welshman/net"
|
||||||
import {deriveEvents} from "@welshman/store"
|
import {deriveEvents} from "@welshman/store"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {formatTimestampRelative, repository} from "@welshman/app"
|
import {repository} from "@welshman/app"
|
||||||
import {notifications} from "@app/notifications"
|
import {notifications} from "@app/notifications"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import type {Snippet} from "svelte"
|
import type {Snippet} from "svelte"
|
||||||
import * as nip19 from "nostr-tools/nip19"
|
import * as nip19 from "nostr-tools/nip19"
|
||||||
|
import {formatTimestamp} from "@welshman/lib"
|
||||||
import {getListTags, getPubkeyTagValues} from "@welshman/util"
|
import {getListTags, getPubkeyTagValues} from "@welshman/util"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {Router} from "@welshman/router"
|
import {Router} from "@welshman/router"
|
||||||
import {formatTimestamp, userMutes} from "@welshman/app"
|
import {userMutes} from "@welshman/app"
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
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"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
|
import {formatTimestampRelative} from "@welshman/lib"
|
||||||
import type {Filter} from "@welshman/util"
|
import type {Filter} from "@welshman/util"
|
||||||
import {deriveEvents} from "@welshman/store"
|
import {deriveEvents} from "@welshman/store"
|
||||||
import {load} from "@welshman/net"
|
import {load} from "@welshman/net"
|
||||||
import {Router} from "@welshman/router"
|
import {Router} from "@welshman/router"
|
||||||
import {repository, loadRelaySelections, formatTimestampRelative} from "@welshman/app"
|
import {repository, loadRelaySelections} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
import Profile from "@app/components/Profile.svelte"
|
import Profile from "@app/components/Profile.svelte"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {nthEq} from "@welshman/lib"
|
import {nthEq, formatTimestamp} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {formatTimestamp} from "@welshman/app"
|
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
import Content from "@app/components/Content.svelte"
|
import Content from "@app/components/Content.svelte"
|
||||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||||
|
|||||||
+13
-9
@@ -71,6 +71,7 @@ export const makeEditor = async ({
|
|||||||
submit,
|
submit,
|
||||||
uploading,
|
uploading,
|
||||||
wordCount,
|
wordCount,
|
||||||
|
disableFileUpload,
|
||||||
}: {
|
}: {
|
||||||
aggressive?: boolean
|
aggressive?: boolean
|
||||||
autofocus?: boolean
|
autofocus?: boolean
|
||||||
@@ -81,6 +82,7 @@ export const makeEditor = async ({
|
|||||||
submit: () => void
|
submit: () => void
|
||||||
uploading?: Writable<boolean>
|
uploading?: Writable<boolean>
|
||||||
wordCount?: Writable<number>
|
wordCount?: Writable<number>
|
||||||
|
disableFileUpload?: boolean
|
||||||
}) => {
|
}) => {
|
||||||
return new Editor({
|
return new Editor({
|
||||||
content,
|
content,
|
||||||
@@ -103,16 +105,18 @@ export const makeEditor = async ({
|
|||||||
aggressive,
|
aggressive,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fileUpload: {
|
fileUpload: disableFileUpload
|
||||||
config: {
|
? false
|
||||||
onDrop() {
|
: {
|
||||||
uploading?.set(true)
|
config: {
|
||||||
|
onDrop() {
|
||||||
|
uploading?.set(true)
|
||||||
|
},
|
||||||
|
onComplete() {
|
||||||
|
uploading?.set(false)
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onComplete() {
|
|
||||||
uploading?.set(false)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nprofile: {
|
nprofile: {
|
||||||
extend: {
|
extend: {
|
||||||
addNodeView: () => makeMentionNodeView(url),
|
addNodeView: () => makeMentionNodeView(url),
|
||||||
|
|||||||
+1
-1
@@ -304,7 +304,7 @@ export const defaultSettings = {
|
|||||||
show_media: true,
|
show_media: true,
|
||||||
hide_sensitive: true,
|
hide_sensitive: true,
|
||||||
report_usage: true,
|
report_usage: true,
|
||||||
report_errors: false,
|
report_errors: true,
|
||||||
send_delay: 3000,
|
send_delay: 3000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {DateInput} from "date-picker-svelte"
|
import {DateInput} from "date-picker-svelte"
|
||||||
import {secondsToDate, dateToSeconds} from "@welshman/app"
|
import {secondsToDate, dateToSeconds} from "@welshman/lib"
|
||||||
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"
|
||||||
|
|
||||||
|
|||||||
+30
-25
@@ -15,6 +15,7 @@
|
|||||||
THREAD,
|
THREAD,
|
||||||
MESSAGE,
|
MESSAGE,
|
||||||
INBOX_RELAYS,
|
INBOX_RELAYS,
|
||||||
|
DIRECT_MESSAGE,
|
||||||
MUTES,
|
MUTES,
|
||||||
FOLLOWS,
|
FOLLOWS,
|
||||||
PROFILE,
|
PROFILE,
|
||||||
@@ -131,31 +132,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await initStorage("flotilla", 8, {
|
|
||||||
...defaultStorageAdapters,
|
|
||||||
events: new EventsStorageAdapter({
|
|
||||||
name: "events",
|
|
||||||
limit: 10_000,
|
|
||||||
repository,
|
|
||||||
rankEvent: (e: TrustedEvent) => {
|
|
||||||
if ([PROFILE, FOLLOWS, MUTES, RELAYS, BLOSSOM_SERVERS, INBOX_RELAYS].includes(e.kind))
|
|
||||||
return 1
|
|
||||||
if ([EVENT_TIME, THREAD, MESSAGE, WRAP].includes(e.kind)) return 0.9
|
|
||||||
|
|
||||||
return 0
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
sleep(300).then(() => ready.resolve())
|
|
||||||
|
|
||||||
defaultSocketPolicies.push(
|
|
||||||
makeSocketPolicyAuth({
|
|
||||||
sign: (event: StampedEvent) => signer.get()?.sign(event),
|
|
||||||
shouldAuth: (socket: Socket) => true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unwrap gift wraps as they come in, but throttled
|
// Unwrap gift wraps as they come in, but throttled
|
||||||
const unwrapper = new TaskQueue<TrustedEvent>({batchSize: 10, processItem: ensureUnwrapped})
|
const unwrapper = new TaskQueue<TrustedEvent>({batchSize: 10, processItem: ensureUnwrapped})
|
||||||
|
|
||||||
@@ -171,6 +147,35 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await initStorage("flotilla", 8, {
|
||||||
|
...defaultStorageAdapters,
|
||||||
|
events: new EventsStorageAdapter({
|
||||||
|
name: "events",
|
||||||
|
limit: 10_000,
|
||||||
|
repository,
|
||||||
|
rankEvent: (e: TrustedEvent) => {
|
||||||
|
if ([PROFILE, FOLLOWS, MUTES, RELAYS, BLOSSOM_SERVERS, INBOX_RELAYS].includes(e.kind)) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([EVENT_TIME, THREAD, MESSAGE, DIRECT_MESSAGE].includes(e.kind)) {
|
||||||
|
return 0.9
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
sleep(300).then(() => ready.resolve())
|
||||||
|
|
||||||
|
defaultSocketPolicies.push(
|
||||||
|
makeSocketPolicyAuth({
|
||||||
|
sign: (event: StampedEvent) => signer.get()?.sign(event),
|
||||||
|
shouldAuth: (socket: Socket) => true,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
// Load relay info
|
// Load relay info
|
||||||
for (const url of INDEXER_RELAYS) {
|
for (const url of INDEXER_RELAYS) {
|
||||||
loadRelay(url)
|
loadRelay(url)
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
import {onMount, onDestroy} from "svelte"
|
import {onMount, onDestroy} from "svelte"
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import type {Readable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
import {now} from "@welshman/lib"
|
import {now, formatTimestampAsDate} from "@welshman/lib"
|
||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {createEvent, MESSAGE, DELETE, REACTION} from "@welshman/util"
|
import {createEvent, MESSAGE, DELETE, REACTION} from "@welshman/util"
|
||||||
import {formatTimestampAsDate, pubkey, publishThunk, deriveRelay} from "@welshman/app"
|
import {pubkey, publishThunk, deriveRelay} from "@welshman/app"
|
||||||
import {slide, fade, fly} from "@lib/transition"
|
import {slide, fade, fly} from "@lib/transition"
|
||||||
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"
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
import type {Readable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
import {readable} from "svelte/store"
|
import {readable} from "svelte/store"
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import {now, last} from "@welshman/lib"
|
import {now, last, formatTimestampAsDate} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {REACTION, DELETE, EVENT_TIME, getTagValue} from "@welshman/util"
|
import {REACTION, DELETE, EVENT_TIME, getTagValue} from "@welshman/util"
|
||||||
import {formatTimestampAsDate} from "@welshman/app"
|
|
||||||
import {fly} from "@lib/transition"
|
import {fly} from "@lib/transition"
|
||||||
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"
|
||||||
|
|||||||
Reference in New Issue
Block a user