feat(parser): improve media parser
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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()} />;
|
||||
}
|
||||
|
||||
@@ -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 });
|
||||
|
||||
Reference in New Issue
Block a user