Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 30 additions & 65 deletions components/pages/posts/post/PostChatWithAi.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<script lang="ts" setup>
import { ChatBubbleLeftEllipsisIcon, SparklesIcon } from '@heroicons/vue/24/outline'
import { flip, offset, shift, useFloating } from '@floating-ui/vue'
import { useChatWithAiReferral } from '~/composables/useAdvertisements'
import useAppStatistics from '~/composables/useAppStatistics'
import type { IPost } from '~/assets/js/post.dto'
import { ChatBubbleLeftEllipsisIcon } from '@heroicons/vue/24/outline'
import { useFloating, offset, flip, shift } from '@floating-ui/vue'
import { useChatWithAiReferral } from '~/composables/useAdvertisements'
import useAppStatistics from '~/composables/useAppStatistics'
import type { IPost } from '~/assets/js/post.dto'

const props = defineProps<{
const props = defineProps<{
tags: IPost['tags']
mediaType: IPost['media_type']
mediaUrl: string | null
}>()

const { chatWithAiReferralTemplate } = useChatWithAiReferral()
Expand All @@ -19,7 +17,7 @@ const props = defineProps<{

const { floatingStyles } = useFloating(referenceEl, floatingEl, {
placement: 'bottom-start',
middleware: [offset(6), flip({ fallbackPlacements: ['bottom-end'] }), shift()]
middleware: [offset(6), flip(), shift()]
})

const tagCandidates = computed(() => {
Expand All @@ -34,9 +32,7 @@ const props = defineProps<{
return Object.values(props.tags).flat()
})

const normalizedTags = computed(() => {
return Array.from(new Set(tagCandidates.value)).filter((tag) => typeof tag === 'string' && tag.trim().length > 0)
})
const normalizedTags = computed(() => Array.from(new Set(tagCandidates.value)))

function formatTagForQuery(tag: string) {
return tag.replaceAll('_', ' ')
Expand All @@ -63,14 +59,6 @@ const props = defineProps<{
return chatWithAiReferralTemplate.value.replace('{query}', encodeURIComponent(query))
}

const nud3Url = computed(() => {
if (props.mediaType !== 'image' || !props.mediaUrl) {
return null
}

return `https://nud3.me/pornify?imageUrl=${encodeURIComponent(props.mediaUrl)}&r=r34`
})

function onChatMenuOpen() {
if (tutorialChatWithAi.value) {
return
Expand All @@ -93,13 +81,12 @@ const props = defineProps<{
>
<ClientOnly>
<ChatBubbleLeftEllipsisIcon
aria-hidden="true"
:class="[
'group-hover:hover-text-util text-base-content h-5 w-5',
!tutorialChatWithAi ? 'chat-with-ai-glow-icon' : ''
]"
aria-hidden="true"
/>

<template #fallback>
<ChatBubbleLeftEllipsisIcon
aria-hidden="true"
Expand All @@ -120,59 +107,37 @@ const props = defineProps<{
:style="floatingStyles"
class="divide-base-0/20 bg-base-1000 ring-base-0/20 z-50 w-56 divide-y rounded-md ring-1 focus:outline-hidden"
>
<div class="text-base-content-highlight px-4 py-2 text-sm font-medium">Chat with AI</div>

<div
v-if="nud3Url"
v-if="!normalizedTags.length"
class="py-1"
>
<div class="text-base-content-highlight px-4 py-2 text-sm font-medium">Fuck with AI</div>
<span class="block px-4 py-2 text-sm"> No tags available </span>
</div>

<HeadlessMenuItem v-slot="{ active }">
<div
v-else
class="py-1"
>
<HeadlessMenuItem
v-for="tag in normalizedTags"
:key="tag"
v-slot="{ active }"
>
<NuxtLink
:class="[active ? 'bg-base-0/20 text-[#F0489C]' : 'text-[#F0489C]']"
:href="nud3Url"
class="group flex w-full items-center gap-2 px-4 py-2 text-sm"
rel="nofollow noopener"
:class="[active ? 'bg-base-0/20 text-base-content-highlight' : 'text-base-content']"
:href="buildReferralUrl(tag)"
class="group flex w-full items-center px-4 py-2 text-sm"
target="_blank"
rel="nofollow noopener"
>
<SparklesIcon
aria-hidden="true"
class="h-5 w-5"
/>
<span class="truncate font-bold">AI Video</span>
<span class="truncate">
{{ formatTagForDisplay(tag) }}
</span>
</NuxtLink>
</HeadlessMenuItem>
</div>

<div class="py-1">
<div class="text-base-content-highlight px-4 py-2 text-sm font-medium">Chat with AI</div>

<template v-if="normalizedTags.length > 0">
<HeadlessMenuItem
v-for="tag in normalizedTags"
:key="tag"
v-slot="{ active }"
>
<NuxtLink
:class="[active ? 'bg-base-0/20 text-base-content-highlight' : 'text-base-content']"
:href="buildReferralUrl(tag)"
class="group flex w-full items-center px-4 py-2 text-sm"
rel="nofollow noopener"
target="_blank"
>
<span class="truncate">
{{ formatTagForDisplay(tag) }}
</span>
</NuxtLink>
</HeadlessMenuItem>
</template>

<span
v-else
class="block px-4 py-2 text-sm"
>
No tags available
</span>
</div>
</HeadlessMenuItems>
</Transition>
</Teleport>
Expand Down
7 changes: 5 additions & 2 deletions components/pages/posts/post/PostComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@
<PostChatWithAi
v-if="!isPremium"
:tags="post.tags"
:mediaType="post.media_type"
:mediaUrl="post.high_res_file.url ?? post.low_res_file.url ?? (mediaFile.file as string)"
/>

<ShareButton
Expand All @@ -156,6 +154,11 @@
class="px-1.5 py-1"
/>

<PostNud3
v-if="post.media_type === 'image' && mediaFile.file"
:mediaUrl="post.high_res_file.url ?? post.low_res_file.url ?? (mediaFile.file as string)"
/>

<button
class="hover:hover-bg-util focus-visible:focus-outline-util group ml-auto flex items-center gap-1 rounded-md px-1.5 py-1"
type="button"
Expand Down
24 changes: 24 additions & 0 deletions components/pages/posts/post/PostNud3.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts" setup>
import { SparklesIcon } from '@heroicons/vue/24/outline'

const props = defineProps({
mediaUrl: {
type: String,
required: true
}
})
</script>

<template>
<a
aria-label="Generate AI Video"
title="Generate AI Video"
class="hover:hover-bg-util focus-visible:focus-outline-util group flex items-center gap-1 rounded-md px-1.5 py-1"
:href="`https://nud3.me/pornify?imageUrl=${encodeURIComponent(mediaUrl)}&r=r34`"
target="_blank"
rel="noopener noreferrer"
>
<SparklesIcon aria-hidden="true" class="group-hover:hover-text-util text-base-content h-5 w-5" />
<span class="group-hover:hover-text-util text-base-content text-xs font-bold">AI</span>
</a>
</template>