Add shadcn/ui tooltip UI && modify from the entire block being a button to just a button (the news publisher is also buttonm the tailwind tooltip is just for the news publisher plubin )

This commit is contained in:
yuanhau 2025-05-27 15:14:49 +08:00
parent d7dfb2fb1d
commit db0c0a3c25
11 changed files with 130 additions and 54 deletions

View file

@ -17,7 +17,7 @@
"@sentry/nuxt": "^9",
"@tailwindcss/vite": "^4.1.5",
"@uploadthing/nuxt": "^7.1.7",
"@vueuse/core": "^13.1.0",
"@vueuse/core": "^13.2.0",
"animate.css": "^4.1.1",
"argon2": "^0.43.0",
"axios": "^1.9.0",

View file

@ -1,4 +1,5 @@
<script setup lang="ts">
import { ScanEyeIcon } from "lucide-vue-next";
import CheckKidUnfriendlyContent from "~/components/checks/checkKidUnfriendlyContent";
const emit = defineEmits(["close", "min", "restore"]);
const staticid = computed(() => props.staticid);
@ -35,9 +36,9 @@ const updateContent = async (url: string, tabAction: boolean) => {
const isPrimary = (url: string, defaultAction: boolean) => {
if (primary.value === url) {
return "text-sky-600 text-bold";
return true;
}
return "text-black";
return false;
};
const openNews = (url: string) => {
@ -72,10 +73,10 @@ watch(
);
const findRel = (title: string) => {
return tf(title);
}
};
const tf = (text: string) => {
const words = text.toLowerCase().split('');
const words = text.toLowerCase().split("");
// const words = text.toLowerCase().match(/[\u4e00-\u9fff]|[a-zA-Z0-9]+/g) || [];
const freqMap = new Map();
@ -92,7 +93,7 @@ const tf = (text: string) => {
}
return tfVector;
}
};
</script>
<template>
<div class="justify-center align-center text-center">
@ -104,8 +105,9 @@ const tf = (text: string) => {
<button
v-for="item in tabs"
@click="updateContent(item.url, true)"
:class="isPrimary(item.url, true)"
:class="isPrimary(item.url, true) ? 'text-sky-600 text-bold' : 'text-black'"
class=""
:disabled="isPrimary(item.url, true)"
>
<span>{{ item.text }}</span>
</button>
@ -129,39 +131,45 @@ const tf = (text: string) => {
:key="item.id"
:class="item.contentType !== 'GENERAL' && 'hidden'"
>
<button @click="openNews(item.url.hash)">
<div class="p-2 bg-gray-200 rounded m-1 p-1">
<h1
class="text-2xl text-bold"
:class="getCheckResult(item.title) ? 'text-red-600' : ''"
<div class="p-2 bg-gray-200 rounded m-1 p-1">
<h1
class="text-2xl text-bold"
:class="getCheckResult(item.title) ? 'text-red-600' : ''"
>
{{ item.title }}
</h1>
<p class="m-0 text-gray-600">
<button >{{ item.publisher }}</button> --
{{
new Date(item.publishTimeUnix).toLocaleString("zh-TW", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: false,
})
}}
</p>
<div class="justify-center align-center text-center flex flex-row p-1">
<button
@click="openNews(item.url.hash)"
class="flex flex-row p-1 bg-sky-300/50 hover:bg-sky-400/50 shadow-lg backdrop-blur-sm rounded transition-all duration-200"
>
{{ item.title }}
</h1>
<p class="m-0 text-gray-600">
{{ item.publisher }} --
{{
new Date(item.publishTimeUnix).toLocaleString("zh-TW", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: false,
})
}}
</p>
<div>
<h3 class="text-lg">類似文章</h3>
<div>{{ findRel(item.title) }}</div>
<!--<div v-for="item in findRel(item.title)">
<ScanEyeIcon class="w-6 h-6 p-1" /><span>觀看文章</span>
</button>
</div>
<div>
<h3 class="text-lg">類似文章</h3>
<div>{{ findRel(item.title) }}</div>
<!--<div v-for="item in findRel(item.title)">
{{ item }}
</div>-->
</div>
<!--<p :class="getCheckResult(item.title) ? 'hidden' : ''">
</div>
<!--<p :class="getCheckResult(item.title) ? 'hidden' : ''">
{{ item.shortDescription }}
</p>-->
</div>
</button>
</div>
</div>
</div>
</Transition>

View file

@ -0,0 +1,14 @@
<script setup lang="ts">
import { TooltipRoot, type TooltipRootEmits, type TooltipRootProps, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<TooltipRootProps>()
const emits = defineEmits<TooltipRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<TooltipRoot v-bind="forwarded">
<slot />
</TooltipRoot>
</template>

View file

@ -0,0 +1,28 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { TooltipContent, type TooltipContentEmits, type TooltipContentProps, TooltipPortal, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(defineProps<TooltipContentProps & { class?: HTMLAttributes['class'] }>(), {
sideOffset: 4,
})
const emits = defineEmits<TooltipContentEmits>()
const delegatedProps = reactiveOmit(props, 'class')
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<TooltipPortal>
<TooltipContent v-bind="{ ...forwarded, ...$attrs }" :class="cn('z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)">
<slot />
</TooltipContent>
</TooltipPortal>
</template>

View file

@ -0,0 +1,11 @@
<script setup lang="ts">
import { TooltipProvider, type TooltipProviderProps } from 'reka-ui'
const props = defineProps<TooltipProviderProps>()
</script>
<template>
<TooltipProvider v-bind="props">
<slot />
</TooltipProvider>
</template>

View file

@ -0,0 +1,11 @@
<script setup lang="ts">
import { TooltipTrigger, type TooltipTriggerProps } from 'reka-ui'
const props = defineProps<TooltipTriggerProps>()
</script>
<template>
<TooltipTrigger v-bind="props">
<slot />
</TooltipTrigger>
</template>

View file

@ -0,0 +1,4 @@
export { default as Tooltip } from './Tooltip.vue'
export { default as TooltipContent } from './TooltipContent.vue'
export { default as TooltipProvider } from './TooltipProvider.vue'
export { default as TooltipTrigger } from './TooltipTrigger.vue'

View file

@ -74,7 +74,7 @@
"aboutNewsOrg": "關於這個新聞來源",
"newsview": "新聞"
},
"tools":{
"tools": {
"title": "工具",
"name": {
"checkweirdkeywords": "檢查偏色情標體",

View file

@ -29,7 +29,7 @@
"@sentry/nuxt": "^9",
"@tailwindcss/vite": "^4.1.5",
"@uploadthing/nuxt": "^7.1.7",
"@vueuse/core": "^13.1.0",
"@vueuse/core": "^13.2.0",
"animate.css": "^4.1.1",
"argon2": "^0.43.0",
"axios": "^1.9.0",

View file

@ -19,8 +19,8 @@ const tools = [
},
];
useSeoMeta({
title: `${t("tools.title")}`
})
title: `${t("tools.title")}`,
});
</script>
<template>
<div

View file

@ -1,14 +1,14 @@
export default defineEventHandler((event) => {
const query = getQuery(event);
const toolCall = query.tool;
const forwardCall = query.forward;
if (toolCall) {
const buildUrl = "/desktop?openapp=" + toolCall;
return sendRedirect(event, buildUrl, 302);
}
if (forwardCall) {
const buildUrl = "/" + forwardCall;
return sendRedirect(event, buildUrl, 302);
}
return sendRedirect(event, "/", 302)
})
const query = getQuery(event);
const toolCall = query.tool;
const forwardCall = query.forward;
if (toolCall) {
const buildUrl = "/desktop?openapp=" + toolCall;
return sendRedirect(event, buildUrl, 302);
}
if (forwardCall) {
const buildUrl = "/" + forwardCall;
return sendRedirect(event, buildUrl, 302);
}
return sendRedirect(event, "/", 302);
});