forked from coracle/flotilla
Add message deletion
This commit is contained in:
@@ -18,9 +18,9 @@
|
|||||||
import Avatar from "@lib/components/Avatar.svelte"
|
import Avatar from "@lib/components/Avatar.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Content from "@app/components/Content.svelte"
|
import Content from "@app/components/Content.svelte"
|
||||||
import EventInfo from "@app/components/EventInfo.svelte"
|
|
||||||
import ChannelThread from "@app/components/ChannelThread.svelte"
|
import ChannelThread from "@app/components/ChannelThread.svelte"
|
||||||
import ChannelMessageEmojiButton from "@app/components/ChannelMessageEmojiButton.svelte"
|
import ChannelMessageEmojiButton from "@app/components/ChannelMessageEmojiButton.svelte"
|
||||||
|
import ChannelMessageMenuButton from "@app/components/ChannelMessageMenuButton.svelte"
|
||||||
import {colors, tagRoom, deriveEvent, displayReaction} from "@app/state"
|
import {colors, tagRoom, deriveEvent, displayReaction} from "@app/state"
|
||||||
import {publishDelete, publishReaction} from "@app/commands"
|
import {publishDelete, publishReaction} from "@app/commands"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
@@ -45,8 +45,6 @@
|
|||||||
derived(publishStatusData, $m => Object.values($m[event.id] || {})),
|
derived(publishStatusData, $m => Object.values($m[event.id] || {})),
|
||||||
)
|
)
|
||||||
|
|
||||||
const showInfo = () => pushModal(EventInfo, {event})
|
|
||||||
|
|
||||||
const findStatus = ($ps: PublishStatusData[], statuses: PublishStatus[]) =>
|
const findStatus = ($ps: PublishStatusData[], statuses: PublishStatus[]) =>
|
||||||
$ps.find(({status}) => statuses.includes(status))
|
$ps.find(({status}) => statuses.includes(status))
|
||||||
|
|
||||||
@@ -152,8 +150,6 @@
|
|||||||
class="join absolute right-1 top-1 border border-solid border-neutral text-xs opacity-0 transition-all group-hover:opacity-100"
|
class="join absolute right-1 top-1 border border-solid border-neutral text-xs opacity-0 transition-all group-hover:opacity-100"
|
||||||
on:click|stopPropagation>
|
on:click|stopPropagation>
|
||||||
<ChannelMessageEmojiButton {url} {room} {event} />
|
<ChannelMessageEmojiButton {url} {room} {event} />
|
||||||
<Button class="btn join-item btn-xs" on:click={showInfo}>
|
<ChannelMessageMenuButton {url} {room} {event} />
|
||||||
<Icon size={4} icon="code-2" />
|
|
||||||
</Button>
|
|
||||||
</button>
|
</button>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {pubkey, publishThunk} from '@welshman/app'
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Confirm from "@lib/components/Confirm.svelte"
|
||||||
|
import EventInfo from "@app/components/EventInfo.svelte"
|
||||||
|
import {makeDelete} from '@app/commands'
|
||||||
|
import {pushModal} from '@app/modal'
|
||||||
|
|
||||||
|
export let url
|
||||||
|
export let event
|
||||||
|
export let onClick
|
||||||
|
|
||||||
|
const showInfo = () => {
|
||||||
|
onClick()
|
||||||
|
pushModal(EventInfo, {event})
|
||||||
|
}
|
||||||
|
|
||||||
|
const showDelete = () => {
|
||||||
|
onClick()
|
||||||
|
pushModal(Confirm, {
|
||||||
|
title: "Delete Message",
|
||||||
|
subtitle: "Are you sure you want to delete this message?",
|
||||||
|
message: `
|
||||||
|
This will send a request to delete this message.
|
||||||
|
Be aware that not all relays may honor this request.`,
|
||||||
|
confirm: async () => {
|
||||||
|
await publishThunk({event: makeDelete({event}), relays: [url]})
|
||||||
|
history.back()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ul class="menu rounded-box bg-base-100 p-2 shadow-xl whitespace-nowrap">
|
||||||
|
<li>
|
||||||
|
<Button on:click={showInfo}>
|
||||||
|
<Icon size={4} icon="code-2" />
|
||||||
|
Message Details
|
||||||
|
</Button>
|
||||||
|
</li>
|
||||||
|
{#if event.pubkey === $pubkey}
|
||||||
|
<li>
|
||||||
|
<Button on:click={showDelete} class="text-error">
|
||||||
|
<Icon size={4} icon="trash-bin-2" />
|
||||||
|
Delete Message
|
||||||
|
</Button>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {type Instance} from "tippy.js"
|
||||||
|
import {between} from "@welshman/lib"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import Tippy from "@lib/components/Tippy.svelte"
|
||||||
|
import ChannelMessageMenu from "@app/components/ChannelMessageMenu.svelte"
|
||||||
|
import {tagRoom} from "@app/state"
|
||||||
|
import {publishReaction} from "@app/commands"
|
||||||
|
|
||||||
|
export let url, room, event
|
||||||
|
|
||||||
|
const open = () => popover.show()
|
||||||
|
|
||||||
|
const onClick = () => popover.hide()
|
||||||
|
|
||||||
|
const onMouseMove = ({clientX, clientY}: any) => {
|
||||||
|
const {x, y, width, height} = popover.popper.getBoundingClientRect()
|
||||||
|
|
||||||
|
if (!between([x, x + width], clientX) || !between([y, y + height + 30], clientY)) {
|
||||||
|
popover.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let popover: Instance
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:document on:mousemove={onMouseMove} />
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<Button class="btn join-item btn-xs" on:click={open}>
|
||||||
|
<Icon icon="menu-dots" size={4} />
|
||||||
|
</Button>
|
||||||
|
<Tippy
|
||||||
|
bind:popover
|
||||||
|
component={ChannelMessageMenu}
|
||||||
|
props={{url, room, event, onClick}}
|
||||||
|
params={{trigger: "manual", interactive: true}} />
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.5 6H3.49991" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
<path d="M18.8333 8.5L18.3734 15.3991C18.1964 18.054 18.1079 19.3815 17.2429 20.1907C16.3779 21 15.0475 21 12.3867 21H11.6133C8.95252 21 7.62212 21 6.75711 20.1907C5.8921 19.3815 5.80361 18.054 5.62661 15.3991L5.16667 8.5" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
<path d="M6.5 6C6.55588 6 6.58382 6 6.60915 5.99936C7.43259 5.97849 8.15902 5.45491 8.43922 4.68032C8.44784 4.65649 8.45667 4.62999 8.47434 4.57697L8.57143 4.28571C8.65431 4.03708 8.69575 3.91276 8.75071 3.8072C8.97001 3.38607 9.37574 3.09364 9.84461 3.01877C9.96213 3 10.0932 3 10.3553 3H13.6447C13.9068 3 14.0379 3 14.1554 3.01877C14.6243 3.09364 15.03 3.38607 15.2493 3.8072C15.3043 3.91276 15.3457 4.03708 15.4286 4.28571L15.5257 4.57697C15.5433 4.62992 15.5522 4.65651 15.5608 4.68032C15.841 5.45491 16.5674 5.97849 17.3909 5.99936C17.4162 6 17.4441 6 17.5 6" stroke="#1C274C" stroke-width="1.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
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 Spinner from "@lib/components/Spinner.svelte"
|
||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
|
|
||||||
@@ -9,10 +10,22 @@
|
|||||||
export let message
|
export let message
|
||||||
export let confirm
|
export let confirm
|
||||||
|
|
||||||
|
let loading = false
|
||||||
|
|
||||||
|
const tryConfirm = async () => {
|
||||||
|
loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
await confirm()
|
||||||
|
} finally {
|
||||||
|
loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="column gap-4" on:submit|preventDefault={confirm}>
|
<form class="column gap-4" on:submit|preventDefault={tryConfirm}>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
<div slot="title">{title}</div>
|
<div slot="title">{title}</div>
|
||||||
<div slot="info">{subtitle}</div>
|
<div slot="info">{subtitle}</div>
|
||||||
@@ -23,8 +36,8 @@
|
|||||||
<Icon icon="alt-arrow-left" />
|
<Icon icon="alt-arrow-left" />
|
||||||
Go back
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="btn btn-primary">
|
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||||
Confirm
|
<Spinner {loading}>Confirm</Spinner>
|
||||||
<Icon icon="alt-arrow-right" />
|
<Icon icon="alt-arrow-right" />
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
import ShopMinimalistic from "@assets/icons/Shop Minimalistic.svg?dataurl"
|
import ShopMinimalistic from "@assets/icons/Shop Minimalistic.svg?dataurl"
|
||||||
import SmileCircle from "@assets/icons/Smile Circle.svg?dataurl"
|
import SmileCircle from "@assets/icons/Smile Circle.svg?dataurl"
|
||||||
import SquareShareLine from "@assets/icons/Square Share Line.svg?dataurl"
|
import SquareShareLine from "@assets/icons/Square Share Line.svg?dataurl"
|
||||||
|
import TrashBin2 from "@assets/icons/Trash Bin 2.svg?dataurl"
|
||||||
import UFO3 from "@assets/icons/UFO 3.svg?dataurl"
|
import UFO3 from "@assets/icons/UFO 3.svg?dataurl"
|
||||||
import UserHeart from "@assets/icons/User Heart.svg?dataurl"
|
import UserHeart from "@assets/icons/User Heart.svg?dataurl"
|
||||||
import UserCircle from "@assets/icons/User Circle.svg?dataurl"
|
import UserCircle from "@assets/icons/User Circle.svg?dataurl"
|
||||||
@@ -137,6 +138,7 @@
|
|||||||
"smile-circle": SmileCircle,
|
"smile-circle": SmileCircle,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
"tag-horizontal": TagHorizontal,
|
"tag-horizontal": TagHorizontal,
|
||||||
|
"trash-bin-2": TrashBin2,
|
||||||
"ufo-3": UFO3,
|
"ufo-3": UFO3,
|
||||||
"square-share-line": SquareShareLine,
|
"square-share-line": SquareShareLine,
|
||||||
"user-heart": UserHeart,
|
"user-heart": UserHeart,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
popover = tippy(element, {
|
popover = tippy(element, {
|
||||||
content: target,
|
content: target,
|
||||||
animation: "shift-away",
|
animation: "shift-away",
|
||||||
|
appendTo: document.querySelector('.tippy-target')!,
|
||||||
...params,
|
...params,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -143,5 +143,6 @@
|
|||||||
<slot />
|
<slot />
|
||||||
</AppContainer>
|
</AppContainer>
|
||||||
<ModalContainer />
|
<ModalContainer />
|
||||||
|
<div class="tippy-target" />
|
||||||
</div>
|
</div>
|
||||||
{/await}
|
{/await}
|
||||||
|
|||||||
Reference in New Issue
Block a user