Compare commits

..

No commits in common. "04ad8ca58e355b022bb01737ae3007d90d1cb4db" and "e72e191b3566dfcc0afd0e188cb89df2384882f1" have entirely different histories.

8 changed files with 32 additions and 133 deletions

View file

@ -14,7 +14,7 @@
# Copy source files # Copy source files
COPY . . COPY . .
RUN bun run generateVersionTag
# Build the application # Build the application
RUN bun run build RUN bun run build

View file

@ -1,14 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
// Vars for translating stuff // Translate stuff
interface translateInterfaceText { interface translateInterfaceText {
translateText: string; translateText: string;
} }
const translateItem: Record<string, translateInterfaceText> = {}; const translateItems: Record<string, translateInterfaceText> = {};
const translateLoading = ref(false);
const displayTranslateContent = ref(false);
const traslateFailed = ref(false);
const translatedBefore = ref(false);
// Imports // Imports
import { ScanEyeIcon, RefreshCcwIcon } from "lucide-vue-next"; import { ScanEyeIcon, RefreshCcwIcon } from "lucide-vue-next";
@ -37,10 +32,18 @@ const emit = defineEmits([
"windowopener", "windowopener",
]); ]);
const props = defineProps<{ const props = defineProps({
applyForTranslation: Boolean; applyForTranslation: {
windowTranslateState: Boolean; type: Boolean,
}>(); required: true,
},
windowTranslateState: {
type: Boolean,
required: true,
},
});
const { applyForTranslation, windowTranslateState } = props;
const openNewWindow = (itemId: string) => { const openNewWindow = (itemId: string) => {
emit("windowopener", "aboutNewsOrg"); emit("windowopener", "aboutNewsOrg");
@ -50,7 +53,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>("domestic"); // Hard code default value as top is just pure garbage. const primary = ref<string>("top"); // Hard code value fn
const canNotLoadTabUI = ref(false); const canNotLoadTabUI = ref(false);
const isDataCached = ref(false); const isDataCached = ref(false);
const pullTabsData = async () => { const pullTabsData = async () => {
@ -81,7 +84,6 @@ 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);
@ -213,64 +215,15 @@ 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)
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
@ -299,16 +252,13 @@ const translateFunction = () => {
class="disabled:cursor-not-allowed" class="disabled:cursor-not-allowed"
:disabled="isPrimary(item.url, true) || switchTabs" :disabled="isPrimary(item.url, true) || switchTabs"
> >
<span>{{ <span>{{ true ? item.text : testmessage }}</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 -->
@ -375,19 +325,11 @@ const translateFunction = () => {
<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">
{{ t("news.articleopenpart1") }}({{ 會打開關於媒體({{ item.publisher }})的視窗
displayTranslateContent
? translateItem[item.publisher].translateText
: item.publisher
}}){{ t("news.articleopenpart2") }}
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
@ -413,20 +355,18 @@ const translateFunction = () => {
@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>{{ <ScanEyeIcon class="w-6 h-6 p-1" /><span>觀看文章</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">{{ t("news.similararticles") }}</h3> <h3 class="text-lg">類似文章</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)"
@ -436,13 +376,8 @@ const translateFunction = () => {
> >
<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">
{{ t("news.similarity") }}: 相似度: {{ (similar.similarity * 100).toFixed(1) }}% |
{{ (similar.similarity * 100).toFixed(1) }}% | {{ similar.item.publisher }}
{{
displayTranslateContent
? translateItem[similar.item.publisher].translateText
: similar.item.publisher
}}
</div> </div>
</div> </div>
</div> </div>
@ -450,7 +385,7 @@ const translateFunction = () => {
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>

View file

@ -10,7 +10,6 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import getVersionTag from "~/versionTag";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const user = ref(""); const user = ref("");
@ -282,20 +281,20 @@ 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>
</div> </div>
<hr /> <hr />
<div class="justiy-center align-center text-center"> <div class="justiy-center align-center text-center">
{{ t("app.settings") }} v0.0.3 || Version: {{ getVersionTag() }} {{ t("app.settings") }} v0.0.3
</div> </div>
</div> </div>
</template> </template>

View file

@ -128,14 +128,5 @@
"contactEmailStarter": "聯絡信箱:" "contactEmailStarter": "聯絡信箱:"
}, },
"copyrightInfo": "版權資訊" "copyrightInfo": "版權資訊"
},
"news": {
"open": "觀看文章",
"opennewwindow": "會打開新的視窗",
"similararticles": "類似文章",
"similarity": "相似度",
"nosimilararticles": "找不到類似文章",
"articleopenpart1": "會打開關於媒體",
"articleopenpart2": "的視窗"
} }
} }

View file

@ -14,8 +14,7 @@
"docs:dev": "vitepress dev docs", "docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs", "docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs", "docs:preview": "vitepress preview docs",
"wipedev": "./clean-dev-env.sh", "wipedev": "./clean-dev-env.sh"
"generateVersionTag": "bun run versionTagGenerate.ts"
}, },
"dependencies": { "dependencies": {
"@fontsource-variable/noto-sans-tc": "^5.2.5", "@fontsource-variable/noto-sans-tc": "^5.2.5",

View file

@ -1,6 +0,0 @@
import versionTag from "~/versionTag";
export default defineEventHandler(() => {
return {
version: versionTag(),
};
});

View file

@ -1,3 +0,0 @@
export default function versionTag() {
return "value";
}

View file

@ -1,16 +0,0 @@
import { $ } from "bun";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
function generateVersionTag() {
let slug = "";
let length = 8;
for (let times = 0; times < length; times++) {
slug += characters.charAt(Math.floor(Math.random() * characters.length));
}
return slug;
}
const tag = generateVersionTag();
// Command
await $`echo 'export default function versionTag() {return "${tag}";}' > ./versionTag.ts`;
console.log("Version Tag:", tag);