djledda.de main
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

GEDeutschArticle.tsx 4.6 KiB

2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
2ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { createTextVNode, computed, defineComponent, h, inject, onServerPrefetch, ref, type VNode, watchEffect } from "vue";
  2. import { RouterLink } from "vue-router";
  3. import useAsyncState from "@/useAsyncState.ts";
  4. import useHead from "@/useHead.ts";
  5. import DJEmail from "@/DJEmail.tsx";
  6. import getDJAPI from "@/api.ts";
  7. export default defineComponent({
  8. name: "ge-deutsch-article",
  9. props: {
  10. articleName: {
  11. type: String,
  12. required: true,
  13. },
  14. },
  15. async setup(props) {
  16. const currentLang = ref<"en" | "de">("de");
  17. function clickBtn() {
  18. currentLang.value = currentLang.value === "en" ? "de" : "en";
  19. }
  20. const parseDom = inject(
  21. "dom-parse",
  22. (innerHTML: string) => Object.assign(document.createElement("div"), { innerHTML }),
  23. );
  24. const { result: articleContent, stateIsReady } = useAsyncState(
  25. "ge-deutsch-article-data",
  26. async ({ hostUrl }) => {
  27. const articleResponse = await fetch(`${hostUrl}/generative-energy/content/${props.articleName}.html`);
  28. const result = await articleResponse.text();
  29. return result;
  30. },
  31. );
  32. const {
  33. result: articleData,
  34. stateIsReady: articleDataReady,
  35. } = useAsyncState('article-data', ({hostUrl}) => getDJAPI(hostUrl, '/rp-articles'));
  36. const articleMetadata = computed(() => articleData.value?.find(_ => _.slug === props.articleName));
  37. useHead({ title: () => articleMetadata.value?.title ?? '' });
  38. function transformArticleNode(node: Node): VNode | string {
  39. if (node.nodeType === node.ELEMENT_NODE) {
  40. const el = node as Element;
  41. const attrs: Record<string, string> = {};
  42. const children = [...node.childNodes].map((_) => transformArticleNode(_));
  43. if (el.tagName === "P") {
  44. (el as HTMLParagraphElement).dataset.tunit = '';
  45. }
  46. if ('dataset' in el && 'tunit' in (el as HTMLElement).dataset) {
  47. if (el.tagName !== 'H1') {
  48. el.classList.add("text-slab");
  49. } else {
  50. el.classList.add("title");
  51. }
  52. if (!('notranslate' in (el as HTMLElement).dataset)) {
  53. children.unshift(h("button", {
  54. class: "swap",
  55. onClick: (e) => {
  56. (e.target as HTMLButtonElement).parentElement?.classList.toggle("swap");
  57. },
  58. }, "↻"));
  59. }
  60. }
  61. for (let i = 0; i < el.attributes.length; i++) {
  62. const item = el.attributes.item(i);
  63. if (item) {
  64. attrs[item.name] = item.value;
  65. }
  66. }
  67. return h((node as Element).tagName, attrs, children);
  68. } else {
  69. return createTextVNode(node.textContent ?? "");
  70. }
  71. }
  72. function ArticleContentTransformed() {
  73. if (articleContent.value) {
  74. const dom = parseDom(articleContent.value);
  75. return h("div", {}, [...dom.children].map((_) => transformArticleNode(_)));
  76. }
  77. return <div>Artikel lädt...</div>;
  78. }
  79. await Promise.all([stateIsReady, articleDataReady]);
  80. return () => (
  81. <div class="ge-article">
  82. <div class="header">
  83. <RouterLink to={{ name: "GEDeutsch" }}>Zur Artikelübersicht</RouterLink>
  84. <button onClick={clickBtn}>
  85. Sprache auf <span>{currentLang.value === "en" ? "Deutsch" : "Englisch"}</span> umschalten
  86. </button>
  87. </div>
  88. <p class="text-slab">
  89. Bei dem untenstehenden Artikel handelt es sich um eine hobbymäßige, amateurhafte Übersetzung des
  90. Artikels „{ articleMetadata.value?.title }“ von Ray Peat. Bei Ungenauigkeiten oder Fehlübersetzungen freue ich mich über <DJEmail>eine Mail</DJEmail>!
  91. </p>
  92. { articleMetadata.value?.tags?.includes('in-arbeit') && <h5 class="baustelle">🚧 Bitte beachte, dass diese Übersetzung noch in Arbeit ist! 🚧</h5> }
  93. <hr />
  94. <article class={`lang-${currentLang.value}`}>
  95. <ArticleContentTransformed />
  96. </article>
  97. </div>
  98. );
  99. },
  100. });