diff --git a/src/components/event/textNote/PreviewedLink.tsx b/src/components/event/textNote/PreviewedLink.tsx
index 92b3e8f..1aa95e2 100644
--- a/src/components/event/textNote/PreviewedLink.tsx
+++ b/src/components/event/textNote/PreviewedLink.tsx
@@ -1,14 +1,15 @@
-import { Component, JSX, Switch, Match, createEffect, Show } from 'solid-js';
+import { Component, JSX, Switch, Match, createSignal, createEffect, Show } from 'solid-js';
import LazyLoad from '@/components/utils/LazyLoad';
import SafeLink from '@/components/utils/SafeLink';
import useConfig from '@/core/useConfig';
-import { useOgp } from '@/utils/ogp';
+import { useTranslation } from '@/i18n/useTranslation';
+import { useOgp, isOgpUrl } from '@/utils/ogp';
import { isTwitterUrl, parseYouTubeVideoUrl } from '@/utils/url';
type PreviewdLinkProps = {
- class?: string;
- href: string;
+ url: string;
+ initialHidden: boolean;
children?: JSX.Element;
};
@@ -29,13 +30,13 @@ const youtubeUrl = (videoId: string): string => {
return iframeUrl.href;
};
-const TwitterEmbed: Component<{ class?: string; href: string }> = (props) => {
+const TwitterEmbed: Component<{ url: string }> = (props) => {
let twitterRef: HTMLQuoteElement | undefined;
const { getColorTheme } = useConfig();
createEffect(() => {
- if (isTwitterUrl(props.href)) {
+ if (isTwitterUrl(props.url)) {
window.twttr?.widgets?.load(twitterRef);
}
});
@@ -51,12 +52,12 @@ const TwitterEmbed: Component<{ class?: string; href: string }> = (props) => {
return (
);
@@ -68,7 +69,7 @@ const OgpEmbed: Component<{ class?: string; url: string }> = (props) => {
}));
return (
- } keyed>
+ } keyed>
{(ogpProps) => (
@@ -89,39 +90,75 @@ const OgpEmbed: Component<{ class?: string; url: string }> = (props) => {
);
};
+type ClickToShowProps = {
+ initialHidden: boolean;
+ url: string;
+ children: JSX.Element;
+};
+
+const ClickToShow: Component = (props) => {
+ const i18n = useTranslation();
+ const [hidden, setHidden] = createSignal(props.initialHidden);
+
+ return (
+
+
+
+
+ }
+ >
+ {props.children}
+
+ );
+};
+
const PreviewedLink: Component = (props) => {
const { config } = useConfig();
return (
- }>
-
-
+ }>
+
+
+
+
-
+
{({ videoId }) => (
-
-
-
- }
- >
- {() => (
-
-
-
- )}
-
+
+
+
+
+ }
+ >
+ {() => (
+
+
+
+ )}
+
+
)}
-
- {() => }
+
+
+ {() => }
+
);
diff --git a/src/components/event/textNote/TextNoteContentDisplay.tsx b/src/components/event/textNote/TextNoteContentDisplay.tsx
index 1d01bb1..64a2736 100644
--- a/src/components/event/textNote/TextNoteContentDisplay.tsx
+++ b/src/components/event/textNote/TextNoteContentDisplay.tsx
@@ -64,7 +64,7 @@ const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
);
}
- return ;
+ return ;
}
if (item.type === 'TagReferenceResolved') {
if (item.reference == null) {
diff --git a/src/locales/en.ts b/src/locales/en.ts
index ceb76d0..b6b3417 100644
--- a/src/locales/en.ts
+++ b/src/locales/en.ts
@@ -108,6 +108,7 @@ export default {
failedToDelete: 'Failed to delete',
showImage: 'Show image',
showVideo: 'Show video',
+ showPreview: 'Show preview',
showOverflow: 'Read more',
hideOverflow: 'Hide',
download: 'Download',
diff --git a/src/locales/ja.ts b/src/locales/ja.ts
index d58d8f4..5ded5b3 100644
--- a/src/locales/ja.ts
+++ b/src/locales/ja.ts
@@ -104,6 +104,7 @@ export default {
failedToDelete: 'すべてのリレーで削除に失敗しました',
showImage: '画像を表示する',
showVideo: '動画を表示する',
+ showPreview: 'プレビューを表示する',
showOverflow: '続きを読む',
hideOverflow: '隠す',
download: 'ダウンロード',
diff --git a/src/utils/ogp.ts b/src/utils/ogp.ts
index e84c9ea..5998442 100644
--- a/src/utils/ogp.ts
+++ b/src/utils/ogp.ts
@@ -39,13 +39,16 @@ export const parseOgp = (text: string): OgpContent | null => {
return parseOgpFromDOM(doc);
};
-export const fetchOgpContent = async (urlString: string): Promise => {
+export const isOgpUrl = (urlString: string): boolean => {
const allowList = ['www3.nhk.or.jp'];
-
const url = new URL(urlString);
- if (!allowList.includes(url.host)) return null;
+ return allowList.includes(url.host);
+};
- const res = await fetch(url, { headers: { Accept: 'text/html' } });
+export const fetchOgpContent = async (urlString: string): Promise => {
+ if (!isOgpUrl(urlString)) return null;
+
+ const res = await fetch(urlString, { headers: { Accept: 'text/html' } });
const text = await res.text();
return parseOgp(text);
};