flotilla/src/app/components/EventActions.svelte

73 lines
2.3 KiB
Svelte
Raw Normal View History

2025-02-06 18:00:25 +00:00
<script lang="ts">
2025-03-18 22:36:52 +00:00
import type {Snippet} from "svelte"
2026-08-29 17:20:39 +00:00
import type {Maybe} from "@welshman/lib"
2025-02-06 18:00:25 +00:00
import type {NativeEmoji} from "emoji-picker-element/shared"
import type {TrustedEvent} from "@welshman/util"
2026-07-28 16:16:26 +00:00
import {tagSpec, tagValue} from "@welshman/util"
2025-09-10 22:26:39 +00:00
import Bolt from "@assets/icons/bolt.svg?dataurl"
import SmileCircle from "@assets/icons/smile-circle.svg?dataurl"
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
2025-02-06 18:00:25 +00:00
import Icon from "@lib/components/Icon.svelte"
import Tippy from "@lib/components/Tippy.svelte"
2026-08-29 17:20:39 +00:00
import type {TippyController} from "@lib/components/Tippy.svelte"
2025-02-06 18:00:25 +00:00
import Button from "@lib/components/Button.svelte"
import EmojiButton from "@lib/components/EmojiButton.svelte"
2026-07-28 16:16:26 +00:00
import ZapButton from "@app/components/ZapButton.svelte"
2025-02-06 18:14:29 +00:00
import EventMenu from "@app/components/EventMenu.svelte"
2026-07-28 16:16:26 +00:00
import {reactions, relays} from "@app/core"
import {ENABLE_ZAPS} from "@app/env"
2025-02-06 18:00:25 +00:00
2025-03-18 22:36:52 +00:00
type Props = {
2025-02-06 18:00:25 +00:00
url: string
2025-02-06 18:14:29 +00:00
noun: string
2025-02-06 18:00:25 +00:00
event: TrustedEvent
2025-07-15 22:56:55 +00:00
hideZap?: boolean
2025-03-18 22:36:52 +00:00
customActions?: Snippet
}
2025-07-15 22:56:55 +00:00
const {url, noun, event, hideZap, customActions}: Props = $props()
2025-02-06 18:00:25 +00:00
2026-07-28 16:16:26 +00:00
const shouldProtect = $relays.hasNip(url, 70)
2026-08-29 17:20:39 +00:00
const showPopover = () => tippy?.show()
const hidePopover = () => tippy?.hide()
2025-02-06 18:00:25 +00:00
2026-07-28 16:16:26 +00:00
const onEmoji = async (emoji: NativeEmoji) => {
const protect = await shouldProtect
const room = tagValue(tagSpec("h"), event.tags)
const command = await $reactions.react(event, emoji.unicode, writer => {
writer.setProtected(protect)
if (room) {
writer.setRoom(url, room)
}
})
2025-02-06 18:00:25 +00:00
2026-07-28 16:16:26 +00:00
return command.publishToRelays([url])
}
2026-08-29 17:20:39 +00:00
let tippy: Maybe<TippyController> = $state()
2025-02-06 18:00:25 +00:00
</script>
<div class="items-center join">
2025-07-17 21:39:59 +00:00
{#if ENABLE_ZAPS && !hideZap}
<ZapButton {url} {event} class="button button-neutral button-xs join-item">
2025-09-10 22:26:39 +00:00
<Icon icon={Bolt} size={4} />
2025-07-15 22:56:55 +00:00
</ZapButton>
{/if}
<EmojiButton {onEmoji} class="button button-neutral button-xs join-item">
2025-09-10 22:26:39 +00:00
<Icon icon={SmileCircle} size={4} />
2025-02-06 18:00:25 +00:00
</EmojiButton>
<Button onclick={showPopover} class="flex join-item button button-neutral button-xs">
<Tippy
2026-08-29 17:20:39 +00:00
bind:controller={tippy}
component={EventMenu}
props={{url, noun, event, customActions, onClick: hidePopover}}
params={{trigger: "manual", interactive: true}}>
2025-09-10 22:26:39 +00:00
<Icon icon={MenuDots} size={4} />
</Tippy>
</Button>
</div>