feat(parser): improve media parser

This commit is contained in:
reya 2023-12-28 08:44:55 +07:00
parent ed538c91c6
commit 4103b509d4
4 changed files with 151 additions and 22 deletions

View File

@ -32,6 +32,7 @@
"@tiptap/extension-mention": "^2.1.13",
"@tiptap/react": "^2.1.13",
"@vidstack/react": "^1.9.8",
"get-urls": "^12.1.0",
"markdown-to-jsx": "^7.3.2",
"minidenticons": "^4.2.0",
"nanoid": "^5.0.4",

View File

@ -1,3 +1,4 @@
import getUrls from "get-urls";
import { nanoid } from "nanoid";
import { nip19 } from "nostr-tools";
import { ReactNode } from "react";
@ -27,6 +28,10 @@ const NOSTR_MENTIONS = [
];
const NOSTR_EVENTS = [
"@nevent1",
"@note1",
"@nostr:note1",
"@nostr:nevent1",
"nostr:note1",
"note1",
"nostr:nevent1",
@ -37,44 +42,68 @@ const NOSTR_EVENTS = [
// const BITCOINS = ['lnbc', 'bc1p', 'bc1q'];
const IMAGES = [".jpg", ".jpeg", ".gif", ".png", ".webp", ".avif", ".tiff"];
const IMAGES = ["jpg", "jpeg", "gif", "png", "webp", "avif", "tiff"];
const VIDEOS = [
".mp4",
".mov",
".webm",
".wmv",
".flv",
".mts",
".avi",
".ogv",
".mkv",
".mp3",
".m3u8",
"mp4",
"mov",
"webm",
"wmv",
"flv",
"mts",
"avi",
"ogv",
"mkv",
"m3u8",
];
export function useRichContent(content: string, textmode = false) {
const AUDIOS = ["mp3", "ogg", "wav"];
export function useRichContent(content: string) {
const storage = useStorage();
let parsedContent: string | ReactNode[] = content.replace(/\n+/g, "\n");
let linkPreview: string;
let images: string[] = [];
let videos: string[] = [];
let audios: string[] = [];
let events: string[] = [];
const text = parsedContent;
const words = text.split(/( |\n)/);
const urls = [...getUrls(text)];
if (!textmode) {
if (storage.settings.media) {
images = words.filter((word) => IMAGES.some((el) => word.endsWith(el)));
videos = words.filter((word) => VIDEOS.some((el) => word.endsWith(el)));
}
events = words.filter((word) =>
NOSTR_EVENTS.some((el) => word.startsWith(el)),
if (storage.settings.media && !storage.settings.lowPowerMode) {
images = urls.filter((word) =>
IMAGES.some((el) => {
const url = new URL(word);
const extension = url.pathname.split(".")[1];
if (extension === el) return true;
return false;
}),
);
videos = urls.filter((word) =>
VIDEOS.some((el) => {
const url = new URL(word);
const extension = url.pathname.split(".")[1];
if (extension === el) return true;
return false;
}),
);
audios = urls.filter((word) =>
AUDIOS.some((el) => {
const url = new URL(word);
const extension = url.pathname.split(".")[1];
if (extension === el) return true;
return false;
}),
);
}
events = words.filter((word) =>
NOSTR_EVENTS.some((el) => word.startsWith(el)),
);
const hashtags = words.filter((word) => word.startsWith("#"));
const mentions = words.filter((word) =>
NOSTR_MENTIONS.some((el) => word.startsWith(el)),
@ -97,6 +126,14 @@ export function useRichContent(content: string, textmode = false) {
}
}
if (audios.length) {
for (const audio of audios) {
parsedContent = reactStringReplace(parsedContent, audio, (match, i) => (
<VideoPreview key={match + i} url={match} />
));
}
}
if (hashtags.length) {
for (const hashtag of hashtags) {
parsedContent = reactStringReplace(
@ -174,7 +211,7 @@ export function useRichContent(content: string, textmode = false) {
(match, i) => {
const url = new URL(match);
if (!linkPreview && !textmode) {
if (!linkPreview) {
linkPreview = match;
return <LinkPreview key={match + i} url={url.toString()} />;
}

View File

@ -2,7 +2,12 @@ import { LoaderIcon } from "@lume/icons";
import { NDKCacheAdapterTauri } from "@lume/ndk-cache-tauri";
import { LumeStorage } from "@lume/storage";
import { QUOTES, delay } from "@lume/utils";
import NDK, { NDKNip46Signer, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
import NDK, {
NDKNip46Signer,
NDKPrivateKeySigner,
NDKRelay,
NDKRelayAuthPolicies,
} from "@nostr-dev-kit/ndk";
import { ndkAdapter } from "@nostr-fetch/adapter-ndk";
import { platform } from "@tauri-apps/plugin-os";
import { relaunch } from "@tauri-apps/plugin-process";
@ -150,6 +155,12 @@ const LumeProvider = ({ children }: PropsWithChildren<object>) => {
// connect
await ndk.connect(3000);
// auth
ndk.relayAuthDefaultPolicy = (relay: NDKRelay, challenge: string) => {
const signIn = NDKRelayAuthPolicies.signIn({ ndk, signer });
return signIn(relay, challenge);
};
// update account's metadata
if (storage.account) {
const user = ndk.getUser({ pubkey: storage.account.pubkey });

View File

@ -498,6 +498,9 @@ importers:
'@vidstack/react':
specifier: ^1.9.8
version: 1.9.8(@types/react@18.2.45)(react@18.2.0)
get-urls:
specifier: ^12.1.0
version: 12.1.0
markdown-to-jsx:
specifier: ^7.3.2
version: 7.3.2(react@18.2.0)
@ -3184,6 +3187,13 @@ packages:
fsevents: 2.3.3
dev: true
/clone-regexp@3.0.0:
resolution: {integrity: sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==}
engines: {node: '>=12'}
dependencies:
is-regexp: 3.1.0
dev: false
/clsx@2.0.0:
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
engines: {node: '>=6'}
@ -3252,6 +3262,11 @@ packages:
engines: {node: '>= 0.6'}
dev: true
/convert-hrtime@5.0.0:
resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==}
engines: {node: '>=12'}
dev: false
/cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
dev: true
@ -3825,6 +3840,11 @@ packages:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
dev: true
/function-timeout@0.1.1:
resolution: {integrity: sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==}
engines: {node: '>=14.16'}
dev: false
/function.prototype.name@1.1.6:
resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
engines: {node: '>= 0.4'}
@ -3865,6 +3885,17 @@ packages:
get-intrinsic: 1.2.2
dev: true
/get-urls@12.1.0:
resolution: {integrity: sha512-qHO+QmPiI1bEw0Y/m+WMAAx/UoEEXLZwEx0DVaKMtlHNrKbMeV960LryIpd+E2Ykb9XkVHmVtpbCsmul3GhR0g==}
engines: {node: '>=16'}
dependencies:
normalize-url: 8.0.0
super-regex: 0.2.0
url-regex-safe: 4.0.0
transitivePeerDependencies:
- re2
dev: false
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@ -4027,6 +4058,11 @@ packages:
loose-envify: 1.4.0
dev: false
/ip-regex@4.3.0:
resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==}
engines: {node: '>=8'}
dev: false
/ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
@ -4140,6 +4176,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/is-regexp@3.1.0:
resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==}
engines: {node: '>=12'}
dev: false
/is-shared-array-buffer@1.0.2:
resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
dependencies:
@ -4563,6 +4604,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/normalize-url@8.0.0:
resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==}
engines: {node: '>=14.16'}
dev: false
/nostr-fetch@0.14.1:
resolution: {integrity: sha512-0r9loOVutJalz8OFK4vMWWcxGlpGdhcR+/xCro/k6V75uRrYchMYNrgJWP3fT7Sn89JtUkUqRYi4P9hh5qdruA==}
dependencies:
@ -5450,6 +5496,15 @@ packages:
ts-interface-checker: 0.1.13
dev: true
/super-regex@0.2.0:
resolution: {integrity: sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==}
engines: {node: '>=14.16'}
dependencies:
clone-regexp: 3.0.0
function-timeout: 0.1.1
time-span: 5.1.0
dev: false
/supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@ -5559,6 +5614,13 @@ packages:
engines: {node: '>=10'}
dev: false
/time-span@5.1.0:
resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==}
engines: {node: '>=12'}
dependencies:
convert-hrtime: 5.0.0
dev: false
/timer2@1.0.0:
resolution: {integrity: sha512-UOZql+P2ET0da+B7V3/RImN3IhC5ghb+9cpecfUhmYGIm0z73dDr3A781nBLnFYmRzeT1AmoT4w9Lgr8n7n7xg==}
dev: true
@ -5581,6 +5643,11 @@ packages:
prosemirror-markdown: 1.12.0
dev: false
/tlds@1.248.0:
resolution: {integrity: sha512-noj0KdpWTBhwsKxMOXk0rN9otg4kTgLm4WohERRHbJ9IY+kSDKr3RmjitaQ3JFzny+DyvBOQKlFZhp0G0qNSfg==}
hasBin: true
dev: false
/to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@ -5804,6 +5871,19 @@ packages:
punycode: 2.3.1
dev: true
/url-regex-safe@4.0.0:
resolution: {integrity: sha512-BrnFCWKNFrFnRzKD66NtJqQepfJrUHNPvPxE5y5NSAhXBb4OlobQjt7907Jm4ItPiXaeX+dDWMkcnOd4jR9N8A==}
engines: {node: '>= 14'}
peerDependencies:
re2: ^1.20.1
peerDependenciesMeta:
re2:
optional: true
dependencies:
ip-regex: 4.3.0
tlds: 1.248.0
dev: false
/use-callback-ref@1.3.0(@types/react@18.2.45)(react@18.2.0):
resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==}
engines: {node: '>=10'}