Coves frontend - a photon fork
at main 128 lines 3.6 kB view raw
1<script lang="ts"> 2 import type { CommentView } from '$lib/api/coves/types' 3 import { coves } from '$lib/api/client.svelte' 4 import { profile } from '$lib/app/auth.svelte' 5 import { errorMessage } from '$lib/app/error' 6 import { t } from '$lib/app/i18n' 7 import { settings } from '$lib/app/settings.svelte' 8 import { Button, Menu, MenuButton, toast } from 'mono-svelte' 9 import { 10 ChatBubbleOvalLeft, 11 EllipsisHorizontal, 12 PencilSquare, 13 Share, 14 Trash, 15 } from 'svelte-hero-icons/dist' 16 import CommentVote from './CommentVote.svelte' 17 18 interface Props { 19 comment: CommentView 20 replying?: boolean 21 disabled?: boolean 22 onedit?: (comment: CommentView) => void 23 } 24 25 let { 26 comment = $bindable(), 27 replying = $bindable(false), 28 disabled = false, 29 onedit, 30 }: Props = $props() 31</script> 32 33<div 34 class={[ 35 'flex flex-row items-center gap-0.5 w-full', 36 settings.posts.reverseActions && 'flex-row-reverse', 37 ]} 38> 39 <CommentVote 40 uri={comment.uri} 41 cid={comment.cid} 42 bind:stats={comment.stats} 43 bind:viewer={comment.viewer} 44 /> 45 <Button 46 color="tertiary" 47 rounding="pill" 48 size="sm" 49 class="text-slate-500 dark:text-zinc-400 gap-1!" 50 onclick={() => (replying = !replying)} 51 disabled={disabled || !profile.current?.jwt} 52 icon={ChatBubbleOvalLeft} 53 > 54 {$t('comment.reply')} 55 </Button> 56 <Menu placement="bottom"> 57 {#snippet target(attachment)} 58 <Button 59 {@attach attachment} 60 title={$t('comment.actions.label')} 61 color="tertiary" 62 rounding="pill" 63 size="square-md" 64 class="text-slate-600 dark:text-zinc-400" 65 icon={EllipsisHorizontal} 66 ></Button> 67 {/snippet} 68 <MenuButton 69 onclick={async () => { 70 try { 71 if (navigator.share) { 72 await navigator.share({ url: comment.uri as string }) 73 } else { 74 await navigator.clipboard.writeText(comment.uri as string) 75 toast({ content: $t('toast.copied'), type: 'success' }) 76 } 77 } catch (err) { 78 if (err instanceof Error && err.name === 'AbortError') return 79 toast({ 80 content: err instanceof Error ? err.message : String(err), 81 type: 'error', 82 }) 83 } 84 }} 85 icon={Share} 86 > 87 {$t('post.actions.more.share')} 88 </MenuButton> 89 {#if profile.current?.jwt} 90 {#if profile.current?.did && profile.current.did === comment.author.did} 91 <MenuButton onclick={() => onedit?.(comment)} icon={PencilSquare}> 92 {$t('post.actions.more.edit')} 93 </MenuButton> 94 {/if} 95 {#if profile.current?.did && profile.current.did === comment.author.did} 96 <MenuButton 97 disabled={comment.isDeleted} 98 color="danger-subtle" 99 onclick={async () => { 100 if (!profile.current?.jwt) return 101 try { 102 await coves().deleteComment({ uri: comment.uri }) 103 comment.isDeleted = true 104 } catch (err) { 105 toast({ 106 content: errorMessage(err), 107 type: 'error', 108 }) 109 } 110 }} 111 icon={Trash} 112 > 113 {$t('post.actions.more.delete')} 114 </MenuButton> 115 {/if} 116 <!-- TODO(coves-migration): Re-enable save when backend API is available --> 117 <MenuButton 118 onclick={() => { 119 toast({ content: 'Reporting is not yet available', type: 'warning' }) 120 }} 121 color="danger-subtle" 122 > 123 Report 124 </MenuButton> 125 {/if} 126 </Menu> 127 <div class="flex-1 w-full"></div> 128</div>