diff --git a/src/app/components/NoteItem.svelte b/src/app/components/NoteItem.svelte index 81e12cf1..df8b742d 100644 --- a/src/app/components/NoteItem.svelte +++ b/src/app/components/NoteItem.svelte @@ -2,6 +2,7 @@ import type {Snippet} from "svelte" import type {NativeEmoji} from "emoji-picker-element/shared" import type {TrustedEvent, EventContent} from "@welshman/util" + import {Router} from "@welshman/router" import SmileCircle from "@assets/icons/smile-circle.svg?dataurl" import Icon from "@lib/components/Icon.svelte" import EmojiButton from "@lib/components/EmojiButton.svelte" @@ -11,26 +12,28 @@ import {publishDelete, publishReaction, canEnforceNip70} from "@app/core/commands" type Props = { - url: string event: TrustedEvent children?: Snippet + url?: string } const {url, event, children}: Props = $props() - const shouldProtect = canEnforceNip70(url) + const relays = url ? [url] : Router.get().Event(event).getUrls() + + const shouldProtect = url ? canEnforceNip70(url) : Promise.resolve(false) const deleteReaction = async (event: TrustedEvent) => - publishDelete({relays: [url], event, protect: await shouldProtect}) + publishDelete({relays, event, protect: await shouldProtect}) const createReaction = async (template: EventContent) => - publishReaction({...template, event, relays: [url], protect: await shouldProtect}) + publishReaction({...template, event, relays, protect: await shouldProtect}) const onEmoji = async (emoji: NativeEmoji) => publishReaction({ event, + relays, content: emoji.unicode, - relays: [url], protect: await shouldProtect, }) diff --git a/src/app/components/ProfileDetail.svelte b/src/app/components/ProfileDetail.svelte index 70727ee4..3dbf68c4 100644 --- a/src/app/components/ProfileDetail.svelte +++ b/src/app/components/ProfileDetail.svelte @@ -15,6 +15,7 @@ import Letter from "@assets/icons/letter-opened.svg?dataurl" import MenuDots from "@assets/icons/menu-dots.svg?dataurl" import MinusCircle from "@assets/icons/minus-circle.svg?dataurl" + import Restart from "@assets/icons/restart.svg?dataurl" import {fly} from "@lib/transition" import Icon from "@lib/components/Icon.svelte" import ImageIcon from "@lib/components/ImageIcon.svelte" @@ -30,7 +31,7 @@ import EventInfo from "@app/components/EventInfo.svelte" import ProfileBadges from "@app/components/ProfileBadges.svelte" import ChatEnable from "@app/components/ChatEnable.svelte" - import {pubkeyLink, deriveUserIsSpaceAdmin} from "@app/core/state" + import {pubkeyLink, deriveUserIsSpaceAdmin, deriveSpaceBannedPubkeyItems} from "@app/core/state" import {pushModal} from "@app/util/modal" import {pushToast} from "@app/util/toast" import {makeChatPath} from "@app/util/routes" @@ -46,6 +47,10 @@ const userIsAdmin = deriveUserIsSpaceAdmin(url) + const bannedPubkeys = url ? deriveSpaceBannedPubkeyItems(url) : undefined + + const isBanned = $derived($bannedPubkeys?.some(item => item.pubkey === pubkey) ?? false) + const back = () => history.back() const chatPath = makeChatPath([pubkey]) @@ -81,6 +86,20 @@ }, }) + const restoreMember = async () => { + const {error} = await manageRelay(url!, { + method: ManagementMethod.AllowPubkey, + params: [pubkey], + }) + + if (error) { + pushToast({theme: "error", message: error}) + } else { + pushToast({message: "User has successfully been restored!"}) + back() + } + } + let showMenu = $state(false) onMount(() => { @@ -112,12 +131,21 @@ {/if} {#if $userIsAdmin} -
  • - -
  • + {#if isBanned} +
  • + +
  • + {:else} +
  • + +
  • + {/if} {/if} diff --git a/src/app/components/ReportDetails.svelte b/src/app/components/ReportDetails.svelte index 06cf399c..0eef7db1 100644 --- a/src/app/components/ReportDetails.svelte +++ b/src/app/components/ReportDetails.svelte @@ -40,9 +40,7 @@ All reports for this event are shown below. {#each $reports.values() as report (report.id)} -
    - -
    + {/each} diff --git a/src/app/components/ReportItem.svelte b/src/app/components/ReportItem.svelte index 8101797f..3faecb1e 100644 --- a/src/app/components/ReportItem.svelte +++ b/src/app/components/ReportItem.svelte @@ -3,14 +3,12 @@ import {getTag, getIdFilters} from "@welshman/util" import {load, LOCAL_RELAY_URL} from "@welshman/net" import type {TrustedEvent} from "@welshman/util" - import {pubkey} from "@welshman/app" import Button from "@lib/components/Button.svelte" import Profile from "@app/components/Profile.svelte" import ProfileName from "@app/components/ProfileName.svelte" import ProfileDetail from "@app/components/ProfileDetail.svelte" import NoteContent from "@app/components/NoteContent.svelte" import ReportMenu from "@app/components/ReportMenu.svelte" - import {publishDelete, canEnforceNip70} from "@app/core/commands" import {pushModal} from "@app/util/modal" import {goToEvent} from "@app/util/routes" @@ -25,7 +23,6 @@ const etag = getTag("e", event.tags) const ptag = getTag("p", event.tags) const reason = etag?.[2] || ptag?.[2] - const shouldProtect = canEnforceNip70(url) const onClick = (e: Event, event: TrustedEvent) => { // @ts-ignore @@ -35,17 +32,12 @@ goToEvent(event) } } - - const deleteReport = async () => { - publishDelete({event, relays: [url], protect: await shouldProtect}) - onDelete?.() - } -
    +
    - + Reported this event {#if reason} @@ -53,11 +45,7 @@ {/if}
    - {#if event.pubkey === $pubkey} - - {:else} - - {/if} +
    {#if event.content}
    diff --git a/src/app/components/ReportMenu.svelte b/src/app/components/ReportMenu.svelte index e3cc81df..48c08108 100644 --- a/src/app/components/ReportMenu.svelte +++ b/src/app/components/ReportMenu.svelte @@ -1,26 +1,32 @@ @@ -32,7 +38,7 @@
    {#each $reports as event (event.id)} - + {:else}

    No reports found.

    {/each} diff --git a/src/app/core/state.ts b/src/app/core/state.ts index 2922bb0f..b2f5fac1 100644 --- a/src/app/core/state.ts +++ b/src/app/core/state.ts @@ -50,6 +50,7 @@ import { makeDeriveItem, deriveItemsByKey, deriveDeduplicated, + deriveEventsById, deriveEventsByIdByUrl, deriveEventsByIdForUrl, getEventsByIdForUrl, @@ -231,6 +232,9 @@ export const deriveEvent = makeDeriveEvent({ onDerive: (filters: Filter[], relays: string[]) => load({filters, relays}), }) +export const deriveEvents = (filters: Filter[] = [{}]) => + deriveEventsDesc(deriveEventsById({repository, filters})) + export const getEventsForUrl = (url: string, filters: Filter[] = [{}]) => getEventsByIdForUrl({url, tracker, repository, filters}).values() diff --git a/src/lib/components/PageContent.svelte b/src/lib/components/PageContent.svelte index 0c9df337..e29379ee 100644 --- a/src/lib/components/PageContent.svelte +++ b/src/lib/components/PageContent.svelte @@ -1,4 +1,5 @@ -
    +
    {@render children?.()}
    diff --git a/src/routes/home/+page.svelte b/src/routes/home/+page.svelte index 1b221d46..daaa0eef 100644 --- a/src/routes/home/+page.svelte +++ b/src/routes/home/+page.svelte @@ -1,77 +1,204 @@ -
    -
    -
    -

    Welcome to

    -

    {PLATFORM_NAME}

    -
    - - - - {#snippet icon()} - - {/snippet} - {#snippet title()} -
    Browse the network
    - {/snippet} - {#snippet info()} -
    Find communities on the nostr network.
    - {/snippet} -
    - - -
    + + {#snippet icon()} +
    +
    -
    -
    + {/snippet} + {#snippet title()} + Recent Activity + {/snippet} + {#snippet action()} +
    + {/snippet} + + + + {#each $recentActivity as { type, event, url, count } (event.id)} + {#if type === "message"} + + {:else if event.kind === THREAD} + + {:else if event.kind === CLASSIFIED} + + {:else if event.kind === ZAP_GOAL} + + {:else if event.kind === EVENT_TIME} + + {:else} + + {/if} + {:else} + {#if loading} +
    + + Loading recent activity... +
    + {:else} +

    No recent activity found!

    + {/if} + {/each} +