mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-24 00:01:03 +08:00
Add translations in to the news window (and also broke it...
This commit is contained in:
parent
e72e191b35
commit
b84a0a6f18
@ -1,10 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// Translate stuff
|
|
||||||
interface translateInterfaceText {
|
|
||||||
translateText: string;
|
|
||||||
}
|
|
||||||
const translateItems: Record<string, translateInterfaceText> = {};
|
|
||||||
|
|
||||||
// Imports
|
// Imports
|
||||||
import { ScanEyeIcon, RefreshCcwIcon } from "lucide-vue-next";
|
import { ScanEyeIcon, RefreshCcwIcon } from "lucide-vue-next";
|
||||||
import {
|
import {
|
||||||
@ -32,16 +26,10 @@ const emit = defineEmits([
|
|||||||
"windowopener",
|
"windowopener",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps<{
|
||||||
applyForTranslation: {
|
applyForTranslation: Boolean;
|
||||||
type: Boolean,
|
windowTranslateState: Boolean;
|
||||||
required: true,
|
}>();
|
||||||
},
|
|
||||||
windowTranslateState: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { applyForTranslation, windowTranslateState } = props;
|
const { applyForTranslation, windowTranslateState } = props;
|
||||||
|
|
||||||
@ -53,7 +41,7 @@ const contentArray = ref([]);
|
|||||||
const errorr = ref(false);
|
const errorr = ref(false);
|
||||||
const switchTabs = ref(false);
|
const switchTabs = ref(false);
|
||||||
const tabs = ref([]);
|
const tabs = ref([]);
|
||||||
const primary = ref<string>("top"); // Hard code value fn
|
const primary = ref<string>("domestic"); // Hard code default value as top is just pure garbage.
|
||||||
const canNotLoadTabUI = ref(false);
|
const canNotLoadTabUI = ref(false);
|
||||||
const isDataCached = ref(false);
|
const isDataCached = ref(false);
|
||||||
const pullTabsData = async () => {
|
const pullTabsData = async () => {
|
||||||
@ -84,6 +72,7 @@ const updateContent = async (url: string, tabAction: boolean) => {
|
|||||||
contentArray.value = [...data.uuidData, ...(data.nuuiddata?.items || [])];
|
contentArray.value = [...data.uuidData, ...(data.nuuiddata?.items || [])];
|
||||||
switchTabs.value = false;
|
switchTabs.value = false;
|
||||||
isDataCached.value = data.cached || false;
|
isDataCached.value = data.cached || false;
|
||||||
|
translatedBefore.value = false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
@ -215,15 +204,73 @@ const openPublisher = (slug: string, title: string) => {
|
|||||||
emit("openNewsSourcePage", slug, title);
|
emit("openNewsSourcePage", slug, title);
|
||||||
};
|
};
|
||||||
const isLoading = computed(() => contentArray.value.length === 0);
|
const isLoading = computed(() => contentArray.value.length === 0);
|
||||||
const testmessage = await translate("嗨", { from: "zh", to: "en" });
|
|
||||||
const shouldHideItem = (item) => {
|
const shouldHideItem = (item) => {
|
||||||
return (
|
return (
|
||||||
item.contentType !== "GENERAL" ||
|
item.contentType !== "GENERAL" ||
|
||||||
item.publisher?.toLowerCase().includes("line")
|
item.publisher?.toLowerCase().includes("line")
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Translate (Selective content)
|
||||||
|
interface translateInterfaceText {
|
||||||
|
translateText: string;
|
||||||
|
}
|
||||||
|
const translateItem: Record<string, translateInterfaceText> = {};
|
||||||
|
|
||||||
|
const translateLoading = ref(false);
|
||||||
|
const displayTranslateContent = ref(false);
|
||||||
|
const traslateFailed = ref(false);
|
||||||
|
const translatedBefore = ref(false);
|
||||||
|
const startTranslating = async (text: string) => {
|
||||||
|
try {
|
||||||
|
translateItem[text] = {
|
||||||
|
translateText: await translate(text, { from: "zh", to: "en" }),
|
||||||
|
};
|
||||||
|
console.log(translateItem[text]);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Translation failed:", error);
|
||||||
|
traslateFailed.value = true;
|
||||||
|
translateItem[text] = { translateText: text }; // fallback
|
||||||
|
}
|
||||||
|
};
|
||||||
|
watch(
|
||||||
|
() => props.applyForTranslation,
|
||||||
|
(value) => {
|
||||||
|
if (value === true || translatedBefore.value === false) {
|
||||||
|
if (translatedBefore.value === true) {
|
||||||
|
displayTranslateContent.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
translateFunction();
|
||||||
|
// NOT retranslating AGAIN when disabling the feat
|
||||||
|
translatedBefore.value = true;
|
||||||
|
} else {
|
||||||
|
displayTranslateContent.value = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const translateFunction = () => {
|
||||||
|
if (canNotLoadTabUI.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
translateLoading.value = true;
|
||||||
|
// Translate tabs
|
||||||
|
for (const tab of tabs.value) {
|
||||||
|
startTranslating(tab.text);
|
||||||
|
}
|
||||||
|
// Translate news titles & news org
|
||||||
|
for (const articleBlock of contentArray.value) {
|
||||||
|
startTranslating(articleBlock.title);
|
||||||
|
startTranslating(articleBlock.publisher);
|
||||||
|
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
displayTranslateContent.value = true;
|
||||||
|
translateLoading.value = false;
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<div v-if="translateLoading">Loading...</div>
|
||||||
<div class="justify-center align-center text-center">
|
<div class="justify-center align-center text-center">
|
||||||
<!--Tabs-->
|
<!--Tabs-->
|
||||||
<div
|
<div
|
||||||
@ -252,13 +299,16 @@ const shouldHideItem = (item) => {
|
|||||||
class="disabled:cursor-not-allowed"
|
class="disabled:cursor-not-allowed"
|
||||||
:disabled="isPrimary(item.url, true) || switchTabs"
|
:disabled="isPrimary(item.url, true) || switchTabs"
|
||||||
>
|
>
|
||||||
<span>{{ true ? item.text : testmessage }}</span>
|
<span>{{
|
||||||
|
displayTranslateContent
|
||||||
|
? translateItem[item.text].translateText
|
||||||
|
: item.text
|
||||||
|
}}</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<button v-if="canNotLoadTabUI"><RefreshCcwIcon /></button>
|
<button v-if="canNotLoadTabUI"><RefreshCcwIcon /></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content Area -->
|
<!-- Content Area -->
|
||||||
<div>
|
<div>
|
||||||
<!-- Loading State -->
|
<!-- Loading State -->
|
||||||
@ -325,11 +375,19 @@ const shouldHideItem = (item) => {
|
|||||||
<button
|
<button
|
||||||
@click="openPublisher(item.publisherId, item.publisher)"
|
@click="openPublisher(item.publisherId, item.publisher)"
|
||||||
>
|
>
|
||||||
{{ item.publisher }}
|
{{
|
||||||
|
displayTranslateContent
|
||||||
|
? translateItem[item.publisher].translateText
|
||||||
|
: item.publisher
|
||||||
|
}}
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent class="rounded">
|
<TooltipContent class="rounded">
|
||||||
會打開關於媒體({{ item.publisher }})的視窗
|
{{ t("news.articleopenpart1") }}({{
|
||||||
|
displayTranslateContent
|
||||||
|
? translateItem[item.publisher].translateText
|
||||||
|
: item.publisher
|
||||||
|
}}){{ t("news.articleopenpart2") }}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
@ -355,18 +413,20 @@ const shouldHideItem = (item) => {
|
|||||||
@click="openNews(item.url.hash, item.title)"
|
@click="openNews(item.url.hash, item.title)"
|
||||||
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"
|
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"
|
||||||
>
|
>
|
||||||
<ScanEyeIcon class="w-6 h-6 p-1" /><span>觀看文章</span>
|
<ScanEyeIcon class="w-6 h-6 p-1" /><span>{{
|
||||||
|
t("news.open")
|
||||||
|
}}</span>
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent class="rounded">
|
<TooltipContent class="rounded">
|
||||||
會打開新的視窗
|
{{ t("news.opennewwindow") }}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg">類似文章</h3>
|
<h3 class="text-lg">{{ t("news.similararticles") }}</h3>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<div
|
<div
|
||||||
v-for="similar in useArgFindRel(item.title, item.publisher)"
|
v-for="similar in useArgFindRel(item.title, item.publisher)"
|
||||||
@ -376,8 +436,13 @@ const shouldHideItem = (item) => {
|
|||||||
>
|
>
|
||||||
<div class="font-medium">{{ similar.title }}</div>
|
<div class="font-medium">{{ similar.title }}</div>
|
||||||
<div class="text-gray-500 text-xs">
|
<div class="text-gray-500 text-xs">
|
||||||
相似度: {{ (similar.similarity * 100).toFixed(1) }}% |
|
{{ t("news.similarity") }}:
|
||||||
{{ similar.item.publisher }}
|
{{ (similar.similarity * 100).toFixed(1) }}% |
|
||||||
|
{{
|
||||||
|
displayTranslateContent
|
||||||
|
? translateItem[similar.item.publisher].translateText
|
||||||
|
: similar.item.publisher
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -385,7 +450,7 @@ const shouldHideItem = (item) => {
|
|||||||
v-if="checkIfEmpty(item.title)"
|
v-if="checkIfEmpty(item.title)"
|
||||||
class="text-gray-500 text-sm"
|
class="text-gray-500 text-sm"
|
||||||
>
|
>
|
||||||
找不到類似文章
|
{{ t("news.nosimilararticles") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -281,13 +281,13 @@ const submitChangeAction = async (action: string) => {
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
|
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
|
||||||
@click="emit('windowopener', 'privacypolicy')"
|
@click="() => emit('windowopener', 'privacypolicy')"
|
||||||
>
|
>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
|
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
|
||||||
@click="emit('windowopener', 'tos')"
|
@click="() => emit('windowopener', 'tos')"
|
||||||
>
|
>
|
||||||
TOS
|
TOS
|
||||||
</button>
|
</button>
|
||||||
|
@ -128,5 +128,14 @@
|
|||||||
"contactEmailStarter": "聯絡信箱:"
|
"contactEmailStarter": "聯絡信箱:"
|
||||||
},
|
},
|
||||||
"copyrightInfo": "版權資訊"
|
"copyrightInfo": "版權資訊"
|
||||||
|
},
|
||||||
|
"news": {
|
||||||
|
"open": "觀看文章",
|
||||||
|
"opennewwindow": "會打開新的視窗",
|
||||||
|
"similararticles": "類似文章",
|
||||||
|
"similarity": "相似度",
|
||||||
|
"nosimilararticles": "找不到類似文章",
|
||||||
|
"articleopenpart1": "會打開關於媒體",
|
||||||
|
"articleopenpart2": "的視窗"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user