From 66bb75797b34a83cdb30e7a8824c52dcf876303d Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Sat, 26 Sep 2026 00:50:26 -0700 Subject: [PATCH] Delete dead lib code and the Card, Badge and Input class wrappers, move the icon workaround into ImageIcon, and type the remaining lib props --- .agents/skills/flotilla-views/SKILL.md | 11 ++- src/app/components/ClassifiedStatus.svelte | 10 ++- src/app/components/Content.svelte | 5 +- src/app/components/EventInfo.svelte | 5 +- src/app/components/HomeHealthChecks.svelte | 3 +- src/app/components/NoteContentPin.svelte | 3 +- src/app/components/PinItem.svelte | 3 +- src/app/components/PomadeSessions.svelte | 9 +-- src/app/components/ProfileInfo.svelte | 5 +- src/app/components/ProfileMultiSelect.svelte | 5 +- src/app/components/ProfileSharedSpaces.svelte | 5 +- src/app/components/RelayItem.svelte | 5 +- src/app/components/ReportItem.svelte | 3 +- src/app/components/RoomJoinItem.svelte | 5 +- src/app/components/Search.svelte | 5 +- src/app/components/SearchBody.svelte | 5 +- src/app/components/SpaceAdmins.svelte | 6 +- .../components/SpaceFeaturedContent.svelte | 5 +- src/app/components/SpaceSearch.svelte | 5 +- src/app/components/ThreadPost.svelte | 3 +- src/app/components/ThunkStatusDetail.svelte | 9 +-- .../hosting/CustomDomainModal.svelte | 41 +++++----- .../components/hosting/InvoiceListItem.svelte | 3 +- .../components/hosting/PaymentSetup.svelte | 11 +-- .../components/hosting/RelayDetailCard.svelte | 45 +++++++---- src/app/components/hosting/RelayForm.svelte | 14 ++-- .../components/hosting/RelayListItem.svelte | 19 +++-- src/app/feeds.ts | 10 ++- src/lib/components/Badge.svelte | 18 ----- src/lib/components/Button.svelte | 13 ++-- src/lib/components/Card.svelte | 38 --------- src/lib/components/Confirm.svelte | 2 +- src/lib/components/FAB.svelte | 10 +-- src/lib/components/Field.svelte | 2 +- src/lib/components/FieldInline.svelte | 2 +- src/lib/components/Icon.svelte | 74 +----------------- src/lib/components/ImageIcon.svelte | 62 ++++++++++++++- src/lib/components/Input.svelte | 29 ------- src/lib/components/InputList.svelte | 3 +- src/lib/components/Link.svelte | 12 +-- src/lib/components/ModalBody.svelte | 2 +- src/lib/components/ModalFooter.svelte | 2 +- src/lib/components/ModalHeader.svelte | 2 +- src/lib/components/ModalSubtitle.svelte | 2 +- src/lib/components/Page.svelte | 2 +- src/lib/components/PageBar.svelte | 2 +- src/lib/components/PageHeader.svelte | 2 +- src/lib/components/PrimaryNavItem.svelte | 16 +++- src/lib/components/Scanner.svelte | 9 ++- src/lib/components/ScrollToTop.svelte | 6 +- src/lib/components/SecondaryNav.svelte | 2 +- src/lib/components/SecondaryNavHeader.svelte | 2 +- src/lib/components/SecondaryNavItem.svelte | 43 +++------- src/lib/components/SecondaryNavSection.svelte | 2 +- src/lib/components/Spinner.svelte | 18 +++-- src/lib/components/StringMultiInput.svelte | 7 +- src/lib/components/SuggestionString.svelte | 5 -- src/lib/components/Suggestions.svelte | 34 ++++++-- src/lib/components/TapTarget.svelte | 9 ++- src/lib/components/ToggleInput.svelte | 22 +----- src/lib/components/secondary-nav.css | 14 ++++ src/lib/feeds.ts | 78 ------------------- src/lib/html.ts | 10 --- src/lib/indexeddb.ts | 16 ++-- src/lib/transition.ts | 71 +++++------------ src/lib/util.ts | 35 +-------- src/routes/settings/about/+page.svelte | 9 +-- src/routes/settings/content/+page.svelte | 21 +++-- src/routes/settings/hosting/+page.svelte | 5 +- src/routes/settings/privacy/+page.svelte | 13 ++-- src/routes/spaces/create/+page.svelte | 3 +- 71 files changed, 385 insertions(+), 602 deletions(-) delete mode 100644 src/lib/components/Badge.svelte delete mode 100644 src/lib/components/Card.svelte delete mode 100644 src/lib/components/Input.svelte delete mode 100644 src/lib/components/SuggestionString.svelte delete mode 100644 src/lib/feeds.ts diff --git a/.agents/skills/flotilla-views/SKILL.md b/.agents/skills/flotilla-views/SKILL.md index 9c940bd1..2f9a8b9c 100644 --- a/.agents/skills/flotilla-views/SKILL.md +++ b/.agents/skills/flotilla-views/SKILL.md @@ -229,11 +229,14 @@ lives there: - page chrome: `Page`, `PageBar`, `PageContent`, `SecondaryNav*`, `PrimaryNavItem`, `FAB` - modal chrome: `Dialog`, `Drawer`, `Modal`, `ModalBody`, `ModalHeader`, `ModalTitle`, `ModalSubtitle`, `ModalFooter`, `Confirm` -- controls: `Button`, `Link`, `Field`, `FieldInline`, `Input`, `InputList`, `ToggleInput`, +- controls: `Button`, `Link`, `Field`, `FieldInline`, `InputList`, `ToggleInput`, `DateTimeInput`, `ImagesInput`, `EmojiPicker`, `MenuButton`, `SegmentedButtons` -- display and lists: `Icon`, `Badge`, `Card`, `Divider`, `Spinner`, `LoadingFallback`, `Tooltip`, +- display and lists: `Icon`, `ImageIcon`, `Divider`, `Spinner`, `LoadingFallback`, `Tooltip`, `Tippy`, `Cv`, `VirtualList`, `Masonry`, `DragList`, `ScrollToTop` -- the CSS component families (`button.css`, `card.css`, …) and the theme tokens +- the CSS component families (`button.css`, `card.css`, `badge.css`, `input.css`, …) and the + theme tokens. Cards, badges and inputs are plain markup with these classes + (`
`, ``, + `
`) rather than components. Anything that takes an identifier and reads a store, publishes, or knows a kind is an app component. A lib component that needs app behavior takes it as a prop, such as `MenuButton`'s @@ -467,7 +470,7 @@ Rich text uses `makeEditor` from `src/app/editor` with `EditorContent`. - Colors are the semantic tokens registered in `base.css`: `bg-surface`, `bg-surface-more`, `text-content`, `text-content-muted`, `border-line`, `text-primary`, `text-error`. The clay, flat, navy and nature themes supply the values through `data-fl-theme`. -- Seven `class:` directives remain as leftovers; everything else builds classes with `cx`. +- A few `class:` directives remain in `src/app` as leftovers; everything else builds classes with `cx`. - Container queries go on the `PageContent`, as in `@2xl:grid-cols-2` for the classifieds grid. - Icons are `import X from "@assets/icons/.svg?dataurl"` with ``, where `size` counts 4px steps. List entries animate with `in:fly` from `@lib/transition`. diff --git a/src/app/components/ClassifiedStatus.svelte b/src/app/components/ClassifiedStatus.svelte index 1369d6bc..4d1a3856 100644 --- a/src/app/components/ClassifiedStatus.svelte +++ b/src/app/components/ClassifiedStatus.svelte @@ -1,8 +1,8 @@ {#if status} - + {ucFirst(status)} - +
{/if} diff --git a/src/app/components/Content.svelte b/src/app/components/Content.svelte index 819e306b..cf500e6e 100644 --- a/src/app/components/Content.svelte +++ b/src/app/components/Content.svelte @@ -26,7 +26,6 @@ import Danger from "@assets/icons/danger-triangle.svg?dataurl" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" - import Card from "@lib/components/Card.svelte" import ContentToken from "@app/components/ContentToken.svelte" import ContentEmoji from "@app/components/ContentEmoji.svelte" import ContentEmail from "@app/components/ContentEmail.svelte" @@ -167,13 +166,13 @@
{#if warning} - +

This note has been flagged by the author as "{warning}".

- +
{:else}
{#each seenOn as url, i (url)} - + {displayRelayUrl(url)} - + {/each}
{/snippet} diff --git a/src/app/components/HomeHealthChecks.svelte b/src/app/components/HomeHealthChecks.svelte index b01584b2..85963b67 100644 --- a/src/app/components/HomeHealthChecks.svelte +++ b/src/app/components/HomeHealthChecks.svelte @@ -3,7 +3,6 @@ import CheckCircle from "@assets/icons/check-circle.svg?dataurl" import Stethoscope from "@assets/icons/stethoscope.svg?dataurl" import Icon from "@lib/components/Icon.svelte" - import Badge from "@lib/components/Badge.svelte" import Button from "@lib/components/Button.svelte" import HomeSection from "@app/components/HomeSection.svelte" import HealthCheckItem from "@app/components/HealthCheckItem.svelte" @@ -48,7 +47,7 @@ {#snippet action()} {#if count > 0} - {count} open + {count} open {/if} {/snippet} {#if count === 0} diff --git a/src/app/components/NoteContentPin.svelte b/src/app/components/NoteContentPin.svelte index bb441f0c..feac442d 100644 --- a/src/app/components/NoteContentPin.svelte +++ b/src/app/components/NoteContentPin.svelte @@ -1,7 +1,6 @@ - +
@@ -44,4 +43,4 @@ Connected {connections} {connections === 1 ? "time" : "times"} - +
diff --git a/src/app/components/ReportItem.svelte b/src/app/components/ReportItem.svelte index 36f3f92a..0690c6f0 100644 --- a/src/app/components/ReportItem.svelte +++ b/src/app/components/ReportItem.svelte @@ -3,7 +3,6 @@ import {getIdFilters, matchTag, tagSpec} from "@welshman/util" import {LOCAL_RELAY_URL} from "@welshman/net" import type {TrustedEvent} from "@welshman/util" - import Card from "@lib/components/Card.svelte" import Cv from "@lib/components/Cv.svelte" import Button from "@lib/components/Button.svelte" import MenuButton from "@lib/components/MenuButton.svelte" @@ -38,7 +37,7 @@ } - +
diff --git a/src/app/components/RoomJoinItem.svelte b/src/app/components/RoomJoinItem.svelte index becebb53..8cc359d0 100644 --- a/src/app/components/RoomJoinItem.svelte +++ b/src/app/components/RoomJoinItem.svelte @@ -1,7 +1,6 @@ - +
- +
diff --git a/src/app/components/Search.svelte b/src/app/components/Search.svelte index cb9a27a4..ca3d164e 100644 --- a/src/app/components/Search.svelte +++ b/src/app/components/Search.svelte @@ -4,7 +4,6 @@ import {publish} from "@welshman/app" import Server from "@assets/icons/server.svg?dataurl" import Icon from "@lib/components/Icon.svelte" - import Badge from "@lib/components/Badge.svelte" import Button from "@lib/components/Button.svelte" import Modal from "@lib/components/Modal.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte" @@ -58,9 +57,9 @@ {#snippet badges(event)} {@const url = getSpaceUrl(event)} {#if url} - + - + {/if} {/snippet} diff --git a/src/app/components/SearchBody.svelte b/src/app/components/SearchBody.svelte index 057fd736..bb92a639 100644 --- a/src/app/components/SearchBody.svelte +++ b/src/app/components/SearchBody.svelte @@ -9,7 +9,6 @@ import Icon from "@lib/components/Icon.svelte" import Spinner from "@lib/components/Spinner.svelte" import Button from "@lib/components/Button.svelte" - import Badge from "@lib/components/Badge.svelte" import ModalBody from "@lib/components/ModalBody.svelte" import PeopleItem from "@app/components/PeopleItem.svelte" import NoteCard from "@app/components/NoteCard.svelte" @@ -164,9 +163,9 @@
- + {formatTimestampRelative(event.created_at)} - + {@render badges?.(event)}
diff --git a/src/app/components/SpaceAdmins.svelte b/src/app/components/SpaceAdmins.svelte index 7e2b4970..2b644625 100644 --- a/src/app/components/SpaceAdmins.svelte +++ b/src/app/components/SpaceAdmins.svelte @@ -3,7 +3,6 @@ import {Relays} from "@welshman/app" import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl" import Pen from "@assets/icons/pen.svg?dataurl" - import Badge from "@lib/components/Badge.svelte" import Button from "@lib/components/Button.svelte" import Icon from "@lib/components/Icon.svelte" import Spinner from "@lib/components/Spinner.svelte" @@ -61,7 +60,7 @@
- Owner + Owner
{/if} {#if loading} @@ -88,7 +87,8 @@
{#each methods as method (method)} - {displayManagementMethod(method)} + {displayManagementMethod(method)} {/each}
diff --git a/src/app/components/SpaceFeaturedContent.svelte b/src/app/components/SpaceFeaturedContent.svelte index 2c6d5dab..28e2dbce 100644 --- a/src/app/components/SpaceFeaturedContent.svelte +++ b/src/app/components/SpaceFeaturedContent.svelte @@ -3,7 +3,6 @@ import Pen from "@assets/icons/pen.svg?dataurl" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" - import Card from "@lib/components/Card.svelte" import Content from "@app/components/Content.svelte" import EditFeaturedContent from "@app/components/EditFeaturedContent.svelte" import {deriveFeaturedContent} from "@app/featured" @@ -23,7 +22,7 @@ {#if $content.length > 0 || $canEdit} - +

@@ -44,5 +43,5 @@ {/each}

{/if} - +
{/if} diff --git a/src/app/components/SpaceSearch.svelte b/src/app/components/SpaceSearch.svelte index f634e210..bc504320 100644 --- a/src/app/components/SpaceSearch.svelte +++ b/src/app/components/SpaceSearch.svelte @@ -1,6 +1,5 @@ @@ -57,7 +56,7 @@

{displayRelayUrl(url)}

-

{addPeriod(relayMessage(status, detail))}

+

{relayMessage(status, detail)}

- {/if} - {/snippet} - +
+ + {#if domain} + + {/if} +
{/snippet} {#snippet info()}

Must be a domain you control, e.g. relay.example.com.

diff --git a/src/app/components/hosting/InvoiceListItem.svelte b/src/app/components/hosting/InvoiceListItem.svelte index 700211e6..6d79c821 100644 --- a/src/app/components/hosting/InvoiceListItem.svelte +++ b/src/app/components/hosting/InvoiceListItem.svelte @@ -1,6 +1,5 @@ {#snippet flagToggle(title: string, flag: RelayFlag, gated = false)} + {#snippet toggle()} + + {/snippet} {#snippet label()} {title} {/snippet} {#snippet input()} - + {#if gated} + + + {@render toggle()} + + {:else} + {@render toggle()} + {/if} {/snippet} {/snippet} @@ -123,12 +132,20 @@

{relay.info_name || relay.subdomain}

- + {ucFirst(relay.status.replace(/_/g, " "))} - - + + {ucFirst(relay.plan_id)} - +
wss://{host} @@ -165,15 +182,15 @@
{relay.custom_domain} {#if domainVerified} - + Verified - + {:else} - + Pending - + {/if}
{#if relay.sync_error} - Failed to sync + Failed to sync {:else} - + {ucFirst(relay.status.replace(/_/g, " "))} - + {/if} {#if !compact} - + {ucFirst(relay.plan_id)} - + Manage {/if}
diff --git a/src/app/feeds.ts b/src/app/feeds.ts index ea53027a..d1c56716 100644 --- a/src/app/feeds.ts +++ b/src/app/feeds.ts @@ -7,9 +7,11 @@ import { ms, now, on, + range, removeUndefined, sleep, uniqBy, + DAY, MONTH, YEAR, } from "@welshman/lib" @@ -37,7 +39,6 @@ import {mergeRepositoryUpdates} from "@welshman/net" import type {RepositoryUpdate} from "@welshman/net" import {createScroller} from "@lib/html" import type {ScrollerOpts} from "@lib/html" -import {daysBetween} from "@lib/util" import {EVENT_CONTEXT_KINDS, REACTION_KINDS} from "@app/content" import {app, network, reader} from "@app/core" @@ -768,7 +769,12 @@ export const makeCalendarFeed = ({ priority: 1, signal: spanSignal(controller.signal), threshold: SPAN_THRESHOLD, - filters: [{kinds: [EVENT_TIME], "#D": daysBetween(since, until).map(String)}], + filters: [ + { + kinds: [EVENT_TIME], + "#D": [...range(since, until, DAY)].map(t => String(Math.floor(t / DAY))), + }, + ], onEose: () => { complete = true }, diff --git a/src/lib/components/Badge.svelte b/src/lib/components/Badge.svelte deleted file mode 100644 index f24dbdd6..00000000 --- a/src/lib/components/Badge.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - - {@render children?.()} - diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte index 81789994..b5bbff23 100644 --- a/src/lib/components/Button.svelte +++ b/src/lib/components/Button.svelte @@ -2,14 +2,9 @@ import type {Snippet} from "svelte" // Behavior only, so the same `button*` classes apply to and without a prop API. - const { - children, - onclick, - type = "button", - ...restProps - }: { + type Props = { children: Snippet - onclick?: (event: Event) => any + onclick?: (event: Event) => unknown type?: "button" | "submit" class?: string style?: string @@ -17,7 +12,9 @@ "data-tip"?: string "aria-label"?: string "aria-pressed"?: boolean - } = $props() + } + + const {children, onclick, type = "button", ...restProps}: Props = $props() const onClick = (e: Event) => { e.preventDefault() diff --git a/src/lib/components/Card.svelte b/src/lib/components/Card.svelte deleted file mode 100644 index 49f9694c..00000000 --- a/src/lib/components/Card.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - {@render children?.()} - diff --git a/src/lib/components/Confirm.svelte b/src/lib/components/Confirm.svelte index b908f5bb..e4d45611 100644 --- a/src/lib/components/Confirm.svelte +++ b/src/lib/components/Confirm.svelte @@ -12,7 +12,7 @@ import Modal from "@lib/components/Modal.svelte" import ModalBody from "@lib/components/ModalBody.svelte" - interface Props { + type Props = { title?: string subtitle?: string message: any diff --git a/src/lib/components/FAB.svelte b/src/lib/components/FAB.svelte index a485ea0b..20c551ea 100644 --- a/src/lib/components/FAB.svelte +++ b/src/lib/components/FAB.svelte @@ -3,15 +3,13 @@ import cx from "classnames" import Button from "@lib/components/Button.svelte" - const { - onclick = () => {}, - className = "", - children, - }: { + type Props = { onclick?: () => void className?: string children?: Snippet - } = $props() + } + + const {onclick = () => {}, className = "", children}: Props = $props()
diff --git a/src/lib/components/Field.svelte b/src/lib/components/Field.svelte index 0433bef7..5efdf22a 100644 --- a/src/lib/components/Field.svelte +++ b/src/lib/components/Field.svelte @@ -1,7 +1,7 @@
diff --git a/src/lib/components/ImageIcon.svelte b/src/lib/components/ImageIcon.svelte index a4eaf4b8..df6fc82b 100644 --- a/src/lib/components/ImageIcon.svelte +++ b/src/lib/components/ImageIcon.svelte @@ -1,4 +1,5 @@ {#if src.includes("image/svg") || src.endsWith(".svg")} - + {:else} {/if} diff --git a/src/lib/components/Input.svelte b/src/lib/components/Input.svelte deleted file mode 100644 index bcca8ec0..00000000 --- a/src/lib/components/Input.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - -
- {@render before?.()} - - {@render after?.()} -
diff --git a/src/lib/components/InputList.svelte b/src/lib/components/InputList.svelte index 75d0d00f..94de254f 100644 --- a/src/lib/components/InputList.svelte +++ b/src/lib/components/InputList.svelte @@ -12,6 +12,7 @@ value: string[] addLabel?: Snippet placeholder?: string + allowAdd?: boolean } type Entry = {id: string; value: string} @@ -21,7 +22,7 @@ addLabel, placeholder = "Enter text...", allowAdd = true, - }: Props & {allowAdd?: boolean} = $props() + }: Props = $props() const toEntry = (value: string) => ({id: randomId(), value}) diff --git a/src/lib/components/Link.svelte b/src/lib/components/Link.svelte index f5e352e9..5e758c81 100644 --- a/src/lib/components/Link.svelte +++ b/src/lib/components/Link.svelte @@ -4,13 +4,7 @@ import {stopPropagation} from "@lib/html" import {navigate} from "@app/modal" - const { - children, - href, - external = false, - replaceState = false, - ...restProps - }: { + type Props = { children?: Snippet href: string external?: boolean @@ -20,7 +14,9 @@ style?: string "data-tip"?: string "aria-label"?: string - } = $props() + } + + const {children, href, external = false, replaceState = false, ...restProps}: Props = $props() const go = (e: Event) => { if (!external) { diff --git a/src/lib/components/ModalBody.svelte b/src/lib/components/ModalBody.svelte index 85c67ea8..9bba6930 100644 --- a/src/lib/components/ModalBody.svelte +++ b/src/lib/components/ModalBody.svelte @@ -2,7 +2,7 @@ import cx from "classnames" import type {Snippet} from "svelte" - interface Props { + type Props = { class?: string children?: Snippet } diff --git a/src/lib/components/ModalFooter.svelte b/src/lib/components/ModalFooter.svelte index 8b1bdf98..390d8d60 100644 --- a/src/lib/components/ModalFooter.svelte +++ b/src/lib/components/ModalFooter.svelte @@ -1,7 +1,7 @@ - -{value} diff --git a/src/lib/components/Suggestions.svelte b/src/lib/components/Suggestions.svelte index db5bfc83..5cc7d3aa 100644 --- a/src/lib/components/Suggestions.svelte +++ b/src/lib/components/Suggestions.svelte @@ -1,22 +1,41 @@ -{#snippet toggle()} - -{/snippet} - - -{#if tooltip} - - {@render toggle()} - -{:else} - {@render toggle()} -{/if} + diff --git a/src/lib/components/secondary-nav.css b/src/lib/components/secondary-nav.css index 99ee18d0..d423ad6b 100644 --- a/src/lib/components/secondary-nav.css +++ b/src/lib/components/secondary-nav.css @@ -1,4 +1,18 @@ @layer components { + .secondary-nav__nav-item { + @apply cursor-pointer rounded-2xl; + padding: 12px 16px; + + &:active:hover, + &:active:focus { + transform: scale(0.97); + } + } + + .secondary-nav__dot { + @apply bg-primary absolute top-5 right-[1.15rem] h-2 w-2 rounded-full; + } + .secondary-nav { @apply border-line mt-sai mb-sai bg-surface-more z-nav max-h-screen min-h-0 w-60 shrink-0 flex-col gap-1 border-r border-solid; diff --git a/src/lib/feeds.ts b/src/lib/feeds.ts deleted file mode 100644 index 82e4d903..00000000 --- a/src/lib/feeds.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {fromPairs, parseJson, randomId} from "@welshman/lib" -import {FEED, Address} from "@welshman/util" -import type {TrustedEvent} from "@welshman/util" -import { - makeIntersectionFeed, - hasSubFeeds, - isTagFeed, - isAuthorFeed, - isScopeFeed, -} from "@welshman/feeds" -import type {Feed as IFeed} from "@welshman/feeds" - -export type Feed = { - title: string - identifier: string - description: string - definition: IFeed - event?: TrustedEvent -} - -export type PublishedFeed = Omit & { - event: TrustedEvent -} - -export const normalizeFeedDefinition = (feed: IFeed) => - hasSubFeeds(feed) ? feed : makeIntersectionFeed(feed) - -export const makeFeed = (feed: Partial = {}): Feed => ({ - title: "", - description: "", - identifier: randomId(), - definition: makeIntersectionFeed(), - ...feed, -}) - -export const readFeed = (event: TrustedEvent) => { - const {d: identifier, title = "", description = "", feed = ""} = fromPairs(event.tags) - const definition = parseJson(feed) || makeIntersectionFeed() - - return {title, identifier, description, definition, event} as PublishedFeed -} - -export const createFeed = ({identifier, definition, title, description}: Feed) => ({ - kind: FEED, - content: "", - tags: [ - ["d", identifier], - ["alt", title], - ["title", title], - ["description", description], - ["feed", JSON.stringify(definition)], - ], -}) - -export const editFeed = (feed: PublishedFeed) => ({ - kind: FEED, - content: feed.event.content, - tags: Object.entries({ - ...fromPairs(feed.event.tags), - title: feed.title, - alt: feed.title, - description: feed.description, - feed: JSON.stringify(feed.definition), - }), -}) - -export const displayFeed = (feed?: Feed) => feed?.title || "[no name]" - -export const isTopicFeed = (f: IFeed) => isTagFeed(f) && f[1] === "#t" - -export const isMentionFeed = (f: IFeed) => isTagFeed(f) && f[1] === "#p" - -export const isAddressFeed = (f: IFeed) => isTagFeed(f) && f[1] === "#a" - -export const isContextFeed = (f: IFeed) => - isTagFeed(f) && f[1] === "#a" && f.slice(2).every(Address.isAddress) - -export const isPeopleFeed = (f: IFeed) => isAuthorFeed(f) || isScopeFeed(f) diff --git a/src/lib/html.ts b/src/lib/html.ts index 891f2f3a..02fdd157 100644 --- a/src/lib/html.ts +++ b/src/lib/html.ts @@ -150,16 +150,6 @@ export const downloadText = async (filename: string, text: string) => { URL.revokeObjectURL(url) } -export const isIntersecting = async (element: Element) => - new Promise(resolve => { - const observer = new IntersectionObserver(xs => { - resolve(xs.some(x => x.isIntersecting)) - observer.unobserve(element) - }) - - observer.observe(element) - }) - export const escapeHtml = (html: string) => { const element = document.createElement("div") diff --git a/src/lib/indexeddb.ts b/src/lib/indexeddb.ts index c44f3de1..7cf596c0 100644 --- a/src/lib/indexeddb.ts +++ b/src/lib/indexeddb.ts @@ -106,15 +106,13 @@ export class IDB { const tx = connection.transaction(table, "readwrite") const store = tx.objectStore(table) - await Promise.all( - Array.from(data).map(item => { - try { - store.put(item) - } catch (e) { - console.error(e, item) - } - }), - ) + for (const item of data) { + try { + store.put(item) + } catch (e) { + console.error(e, item) + } + } await tx.done } diff --git a/src/lib/transition.ts b/src/lib/transition.ts index 9d80e5ae..2068b9ba 100644 --- a/src/lib/transition.ts +++ b/src/lib/transition.ts @@ -1,6 +1,5 @@ -// @ts-nocheck import {cubicOut} from "svelte/easing" -import type {FlyParams} from "svelte/transition" +import type {FlyParams, SlideParams} from "svelte/transition" import {fly as baseFly} from "svelte/transition" export {fade, slide} from "svelte/transition" @@ -44,62 +43,28 @@ export const translate = ( } } -// Copy-pasted and tweaked from slide source code -export function slideAndFade( - node: any, - {delay = 0, duration = 400, easing = cubicOut, axis = "y"} = {}, -) { +export const slideAndFade = ( + node: Element, + {delay = 0, duration = 400, easing = cubicOut, axis = "y"}: SlideParams = {}, +) => { const style = getComputedStyle(node) - const primary_property = axis === "y" ? "height" : "width" - const primary_property_value = parseFloat(style[primary_property]) - const secondary_properties = axis === "y" ? ["top", "bottom"] : ["left", "right"] - const capitalized_secondary_properties = secondary_properties.map( - (e: string) => `${e[0].toUpperCase()}${e.slice(1)}`, - ) - const padding_start_value = parseFloat(style[`padding${capitalized_secondary_properties[0]}`]) - const padding_end_value = parseFloat(style[`padding${capitalized_secondary_properties[1]}`]) - const margin_start_value = parseFloat(style[`margin${capitalized_secondary_properties[0]}`]) - const margin_end_value = parseFloat(style[`margin${capitalized_secondary_properties[1]}`]) - const border_width_start_value = parseFloat( - style[`border${capitalized_secondary_properties[0]}Width`], - ) - const border_width_end_value = parseFloat( - style[`border${capitalized_secondary_properties[1]}Width`], - ) + const [start, end] = axis === "y" ? ["top", "bottom"] : ["left", "right"] + const sizes = [ + axis === "y" ? "height" : "width", + `padding-${start}`, + `padding-${end}`, + `margin-${start}`, + `margin-${end}`, + `border-${start}-width`, + `border-${end}-width`, + ].map((property): [string, number] => [property, parseFloat(style.getPropertyValue(property))]) + return { delay, duration, easing, css: (t: number) => - "overflow: hidden;" + - `opacity: ${t};` + - `${primary_property}: ${t * primary_property_value}px;` + - `padding-${secondary_properties[0]}: ${t * padding_start_value}px;` + - `padding-${secondary_properties[1]}: ${t * padding_end_value}px;` + - `margin-${secondary_properties[0]}: ${t * margin_start_value}px;` + - `margin-${secondary_properties[1]}: ${t * margin_end_value}px;` + - `border-${secondary_properties[0]}-width: ${t * border_width_start_value}px;` + - `border-${secondary_properties[1]}-width: ${t * border_width_end_value}px;`, + `overflow: hidden;opacity: ${t};` + + sizes.map(([property, size]) => `${property}: ${t * size}px;`).join(""), } } - -export type ScaleParams = { - delay?: number - duration?: number - easing?: (t: number) => number - start?: number -} - -export const scale = ( - node: Element, - {delay = 0, duration = 200, easing = cubicOut, start = 0.96}: ScaleParams = {}, -) => ({ - delay, - duration, - easing, - css: (t: number) => { - const s = start + (1 - start) * t - - return `transform: scale(${s}); opacity: ${t}` - }, -}) diff --git a/src/lib/util.ts b/src/lib/util.ts index 5d104c74..53f67d28 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -1,28 +1,9 @@ -import {identity, range, DAY, hexToBytes, bytesToHex} from "@welshman/lib" -import {fromNostrURI} from "@welshman/util" +import {tryCatch, hexToBytes, bytesToHex} from "@welshman/lib" +import {fromNostrURI, Pubkey} from "@welshman/util" import * as nip19 from "nostr-tools/nip19" -export const decodePubkey = (entity: string): string | undefined => { - if (/^[a-f0-9]{64}$/i.test(entity)) { - return entity.toLowerCase() - } - - try { - const decoded = nip19.decode(fromNostrURI(entity)) - - if (decoded.type === "npub") { - return decoded.data - } - - if (decoded.type === "nprofile") { - return decoded.data.pubkey - } - - return undefined - } catch { - return undefined - } -} +export const decodePubkey = (entity: string) => + tryCatch(() => Pubkey.from(fromNostrURI(entity).toLowerCase()).pubkey) export const nsecEncode = (secret: string) => nip19.nsecEncode(hexToBytes(secret)) @@ -36,10 +17,6 @@ export const nsecDecode = (nsec: string) => { return bytesToHex(data) } -export const day = (seconds: number) => Math.floor(seconds / DAY) - -export const daysBetween = (start: number, end: number) => [...range(start, end, DAY)].map(day) - export const ucFirst = (s: string) => s.slice(0, 1).toUpperCase() + s.slice(1) export const errorMessage = (err: unknown) => String(err).replace(/^.*Error: /, "") @@ -52,10 +29,6 @@ export const buildUrl = (base: string | URL, ...pathname: string[]) => { return url.toString() } -export const addPeriod = (s: string) => (s + ".").replace(/\.+$/, ".") - export const normalizeTopic = (topic: string) => topic.trim().replace(/^#+/, "").toLowerCase() -export const fromCsv = (s: string) => (s || "").split(",").filter(identity) - export const stripPrefix = (m: string) => m.replace(/^\w+: /, "") diff --git a/src/routes/settings/about/+page.svelte b/src/routes/settings/about/+page.svelte index 3f7d89c9..90c5caf4 100644 --- a/src/routes/settings/about/+page.svelte +++ b/src/routes/settings/about/+page.svelte @@ -2,7 +2,6 @@ import Link from "@lib/components/Link.svelte" import Button from "@lib/components/Button.svelte" import Icon from "@lib/components/Icon.svelte" - import Card from "@lib/components/Card.svelte" import Code from "@assets/icons/code-2.svg?dataurl" import Planet from "@assets/icons/planet.svg?dataurl" import Pen from "@assets/icons/pen.svg?dataurl" @@ -27,19 +26,19 @@

{PLATFORM_NAME}

{#if ENABLE_ZAPS} - +

Donate

Funds will be used to support development.

- +
{/if} - +

Get in touch

Having problems? Let us know.

Get Support - +
diff --git a/src/routes/settings/content/+page.svelte b/src/routes/settings/content/+page.svelte index e0ed5c29..7f6447d3 100644 --- a/src/routes/settings/content/+page.svelte +++ b/src/routes/settings/content/+page.svelte @@ -17,7 +17,6 @@ import InputList from "@lib/components/InputList.svelte" import Link from "@lib/components/Link.svelte" import Icon from "@lib/components/Icon.svelte" - import Card from "@lib/components/Card.svelte" import Button from "@lib/components/Button.svelte" import Spinner from "@lib/components/Spinner.svelte" import PageContent from "@lib/components/PageContent.svelte" @@ -107,7 +106,7 @@
- +
Content Settings @@ -146,8 +145,8 @@
{/snippet} -
- +
+
Theme Settings @@ -182,8 +181,8 @@

Changes the shape and texture of everything, not just its colors.

{/snippet} - - +
+
Accessibility @@ -206,8 +205,8 @@ bind:value={$settings.font_size} /> {/snippet} - - +
+
Editor Settings {#snippet label()} @@ -271,13 +270,13 @@

Choose a media server type and url for files you upload to {PLATFORM_NAME}.

{/snippet}
- - +
+
- +
diff --git a/src/routes/settings/hosting/+page.svelte b/src/routes/settings/hosting/+page.svelte index 21a58d04..8b0605c2 100644 --- a/src/routes/settings/hosting/+page.svelte +++ b/src/routes/settings/hosting/+page.svelte @@ -10,7 +10,6 @@ import Bill from "@assets/icons/bill.svg?dataurl" import DangerCircle from "@assets/icons/danger-circle.svg?dataurl" import Icon from "@lib/components/Icon.svelte" - import Badge from "@lib/components/Badge.svelte" import Button from "@lib/components/Button.svelte" import Spinner from "@lib/components/Spinner.svelte" import PageContent from "@lib/components/PageContent.svelte" @@ -235,9 +234,9 @@ Payment Methods
{#if tenant} - + {status} - + {/if}
    diff --git a/src/routes/settings/privacy/+page.svelte b/src/routes/settings/privacy/+page.svelte index 6255c576..7c4ac674 100644 --- a/src/routes/settings/privacy/+page.svelte +++ b/src/routes/settings/privacy/+page.svelte @@ -8,7 +8,6 @@ import FieldInline from "@lib/components/FieldInline.svelte" import ToggleInput from "@lib/components/ToggleInput.svelte" import Icon from "@lib/components/Icon.svelte" - import Card from "@lib/components/Card.svelte" import PageContent from "@lib/components/PageContent.svelte" import Button from "@lib/components/Button.svelte" import Spinner from "@lib/components/Spinner.svelte" @@ -87,7 +86,7 @@
    - +
    Privacy Settings @@ -147,8 +146,8 @@

    {/snippet} - - +
    +
    Message Requests @@ -201,13 +200,13 @@

    A sender counts as known when this many of the people you follow also follow them.

    {/snippet} - - +
    +
    - +
    diff --git a/src/routes/spaces/create/+page.svelte b/src/routes/spaces/create/+page.svelte index c2aa3ede..52a2767a 100644 --- a/src/routes/spaces/create/+page.svelte +++ b/src/routes/spaces/create/+page.svelte @@ -4,7 +4,6 @@ import ArrowRight from "@assets/icons/arrow-right.svg?dataurl" import Link from "@lib/components/Link.svelte" import Button from "@lib/components/Button.svelte" - import Badge from "@lib/components/Badge.svelte" import Icon from "@lib/components/Icon.svelte" import Page from "@lib/components/Page.svelte" import PageHeader from "@lib/components/PageHeader.svelte" @@ -35,7 +34,7 @@
    {PLATFORM_NAME} Logo - Recommended + Recommended