diff --git a/app/app.vue b/app/app.vue index 898cc04..0efe9cc 100644 --- a/app/app.vue +++ b/app/app.vue @@ -9,5 +9,5 @@ import 'vue-sonner/style.css' - + diff --git a/app/components/changelog/ChangelogReactions.vue b/app/components/changelog/ChangelogReactions.vue index 1231540..ba9f728 100644 --- a/app/components/changelog/ChangelogReactions.vue +++ b/app/components/changelog/ChangelogReactions.vue @@ -15,6 +15,10 @@ const picked = reactive>({}) const pickerOpen = ref(false) const rootRef = ref(null) +const { data: session } = useAuthSession() +const isLoggedIn = computed(() => !!session.value?.user) +const loginModal = useLoginModal() + // Initialize picked state from userReactions for (const emoji of props.userReactions) { picked[emoji] = true @@ -29,6 +33,11 @@ const displayedReactions = computed(() => ) async function toggle(emoji: string) { + if (!isLoggedIn.value) { + pickerOpen.value = false + return loginModal.open() + } + const wasActive = picked[emoji] // Optimistic update diff --git a/app/components/post/PostDetail.vue b/app/components/post/PostDetail.vue index 00884ec..d9f4fdb 100644 --- a/app/components/post/PostDetail.vue +++ b/app/components/post/PostDetail.vue @@ -2,6 +2,7 @@ import { MdEditor } from 'md-editor-v3' import 'md-editor-v3/lib/style.css' import '~/assets/css/md-editor-preview.css' +import { toast } from 'vue-sonner' import { sanitizeAttachmentHtml } from '~/utils/attachment'; @@ -280,6 +281,17 @@ async function handleDeleteComment(commentId: string) { watch(commentSort, () => { store.fetchComments(props.slug, commentSort.value) }) + +async function handleShare() { + // Canonical post URL — independent of current location (post may be opened in a modal) + const url = `${window.location.origin}/p/${props.slug}` + try { + await navigator.clipboard.writeText(url) + toast.success('Link copied to clipboard') + } catch { + toast.error('Failed to copy link') + } +}