|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import { createTextVNode, computed, defineComponent, h, inject, onServerPrefetch, ref, type VNode, watchEffect } from "vue";
- import { RouterLink } from "vue-router";
- import useAsyncState from "@/useAsyncState.ts";
- import useHead from "@/useHead.ts";
- import DJEmail from "@/DJEmail.tsx";
- import getDJAPI from "@/api.ts";
-
- export default defineComponent({
- name: "ge-deutsch-article",
- props: {
- articleName: {
- type: String,
- required: true,
- },
- },
- async setup(props) {
- const currentLang = ref<"en" | "de">("de");
-
- function clickBtn() {
- currentLang.value = currentLang.value === "en" ? "de" : "en";
- }
-
- const parseDom = inject(
- "dom-parse",
- (innerHTML: string) => Object.assign(document.createElement("div"), { innerHTML }),
- );
-
- const { result: articleContent, stateIsReady } = useAsyncState(
- "ge-deutsch-article-data",
- async ({ hostUrl }) => {
- const articleResponse = await fetch(`${hostUrl}/generative-energy/content/${props.articleName}.html`);
- const result = await articleResponse.text();
- return result;
- },
- );
-
- const {
- result: articleData,
- stateIsReady: articleDataReady,
- } = useAsyncState('article-data', ({hostUrl}) => getDJAPI(hostUrl, '/rp-articles'));
-
- const articleMetadata = computed(() => articleData.value?.find(_ => _.slug === props.articleName));
-
- useHead({
- title: () => articleMetadata.value?.title ?? '',
- metatags: () => articleMetadata.value ? [
- { name: 'title', content: articleMetadata.value.title },
- { name: 'author', content: articleMetadata.value.author },
- ] : [],
- });
-
- function transformArticleNode(node: Node): VNode | string {
- if (node.nodeType === node.ELEMENT_NODE) {
- const el = node as Element;
- const attrs: Record<string, string> = {};
- const children = [...node.childNodes].map((_) => transformArticleNode(_));
-
- if (el.attributes.getNamedItem('lang')?.value === 'en') {
- el.ariaHidden = 'true';
- }
-
- if (el.tagName === "P") {
- (el as HTMLParagraphElement).dataset.tunit = '';
- }
- if ('dataset' in el && 'tunit' in (el as HTMLElement).dataset) {
- if (el.tagName !== 'H1') {
- el.classList.add("text-slab");
- } else {
- el.classList.add("title");
- }
- if (!('notranslate' in (el as HTMLElement).dataset)) {
- children.unshift(h("button", {
- class: "swap",
- onClick: (e) => {
- (e.target as HTMLButtonElement).parentElement?.classList.toggle("swap");
- },
- }, "↻"));
- }
- }
-
- for (let i = 0; i < el.attributes.length; i++) {
- const item = el.attributes.item(i);
- if (item) {
- attrs[item.name] = item.value;
- }
- }
-
- return h((node as Element).tagName, attrs, children);
- } else {
- return createTextVNode(node.textContent ?? "");
- }
- }
-
- function ArticleContentTransformed() {
- if (articleContent.value) {
- const dom = parseDom(articleContent.value);
- return h("div", {}, [...dom.children].map((_) => transformArticleNode(_)));
- }
- return <div>Artikel lädt...</div>;
- }
-
- await Promise.all([stateIsReady, articleDataReady]);
-
- return () => (
- <div class="ge-article">
- <div class="header">
- <RouterLink to={{ name: "GEDeutsch" }}>Zur Artikelübersicht</RouterLink>
- <button onClick={clickBtn}>
- Sprache auf <span>{currentLang.value === "en" ? "Deutsch" : "Englisch"}</span> umschalten
- </button>
- </div>
- <p class="text-slab">
- Bei dem untenstehenden Artikel handelt es sich um eine hobbymäßige, amateurhafte Übersetzung des
- Artikels „{ articleMetadata.value?.titleEn }“ von Ray Peat. Bei Ungenauigkeiten oder Fehlübersetzungen freue ich mich über <DJEmail>eine Mail</DJEmail>!
- </p>
- { articleMetadata.value?.tags?.includes('in-arbeit') && <h5 class="baustelle">🚧 Bitte beachte, dass diese Übersetzung noch in Arbeit ist! 🚧</h5> }
- <hr />
- <article class={`lang-${currentLang.value}`}>
- <ArticleContentTransformed />
- </article>
- </div>
- );
- },
- });
|