rome -> eslint + prettier
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { readBinaryFile } from "@tauri-apps/api/fs";
|
||||
import { readBinaryFile } from '@tauri-apps/api/fs';
|
||||
|
||||
export async function createBlobFromFile(path: string): Promise<Blob> {
|
||||
const file = await readBinaryFile(path);
|
||||
return new Blob([file]);
|
||||
const file = await readBinaryFile(path);
|
||||
return new Blob([file]);
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
import updateLocale from "dayjs/plugin/updateLocale";
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import updateLocale from 'dayjs/plugin/updateLocale';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
dayjs.extend(updateLocale);
|
||||
|
||||
dayjs.updateLocale("en", {
|
||||
relativeTime: {
|
||||
past: "%s ago",
|
||||
s: "just now",
|
||||
m: "1m",
|
||||
mm: "%dm",
|
||||
h: "1h",
|
||||
hh: "%dh",
|
||||
d: "1d",
|
||||
dd: "%dd",
|
||||
},
|
||||
dayjs.updateLocale('en', {
|
||||
relativeTime: {
|
||||
past: '%s ago',
|
||||
s: 'just now',
|
||||
m: '1m',
|
||||
mm: '%dm',
|
||||
h: '1h',
|
||||
hh: '%dh',
|
||||
d: '1d',
|
||||
dd: '%dd',
|
||||
},
|
||||
});
|
||||
|
||||
export function formatCreatedAt(time, message = false) {
|
||||
let formated;
|
||||
let formated;
|
||||
|
||||
const now = dayjs();
|
||||
const inputTime = dayjs.unix(time);
|
||||
const diff = now.diff(inputTime, "hour");
|
||||
const now = dayjs();
|
||||
const inputTime = dayjs.unix(time);
|
||||
const diff = now.diff(inputTime, 'hour');
|
||||
|
||||
if (message) {
|
||||
if (diff < 12) {
|
||||
formated = inputTime.format("HH:mm A");
|
||||
} else {
|
||||
formated = inputTime.format("MMM DD");
|
||||
}
|
||||
} else {
|
||||
if (diff < 24) {
|
||||
formated = inputTime.from(now, true);
|
||||
} else {
|
||||
formated = inputTime.format("MMM DD");
|
||||
}
|
||||
}
|
||||
if (message) {
|
||||
if (diff < 12) {
|
||||
formated = inputTime.format('HH:mm A');
|
||||
} else {
|
||||
formated = inputTime.format('MMM DD');
|
||||
}
|
||||
} else {
|
||||
if (diff < 24) {
|
||||
formated = inputTime.from(now, true);
|
||||
} else {
|
||||
formated = inputTime.format('MMM DD');
|
||||
}
|
||||
}
|
||||
|
||||
return formated;
|
||||
return formated;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// get X days ago with user provided date
|
||||
export function getDayAgo(numOfDays, date = new Date()) {
|
||||
const days = new Date(date.getTime());
|
||||
days.setDate(date.getDate() - numOfDays);
|
||||
const days = new Date(date.getTime());
|
||||
days.setDate(date.getDate() - numOfDays);
|
||||
|
||||
return days;
|
||||
return days;
|
||||
}
|
||||
|
||||
// get X hours ago with user provided date
|
||||
export function getHourAgo(numOfHours, date = new Date()) {
|
||||
const hours = new Date(date.getTime());
|
||||
hours.setHours(date.getHours() - numOfHours);
|
||||
const hours = new Date(date.getTime());
|
||||
hours.setHours(date.getHours() - numOfHours);
|
||||
|
||||
return hours;
|
||||
return hours;
|
||||
}
|
||||
|
||||
// convert date to unix timestamp
|
||||
export function dateToUnix(_date?: Date) {
|
||||
const date = _date || new Date();
|
||||
const date = _date || new Date();
|
||||
|
||||
return Math.floor(date.getTime() / 1000);
|
||||
return Math.floor(date.getTime() / 1000);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { getActiveAccount } from "@libs/storage";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { getActiveAccount } from '@libs/storage';
|
||||
|
||||
export function useAccount() {
|
||||
const { status, data: account } = useQuery(
|
||||
["currentAccount"],
|
||||
async () => await getActiveAccount(),
|
||||
{
|
||||
staleTime: Infinity,
|
||||
refetchOnMount: true,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: true,
|
||||
},
|
||||
);
|
||||
const { status, data: account } = useQuery(
|
||||
['currentAccount'],
|
||||
async () => await getActiveAccount(),
|
||||
{
|
||||
staleTime: Infinity,
|
||||
refetchOnMount: true,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: true,
|
||||
}
|
||||
);
|
||||
|
||||
return { status, account };
|
||||
return { status, account };
|
||||
}
|
||||
|
||||
@@ -1,44 +1,48 @@
|
||||
import { createNote, getNoteByID } from "@libs/storage";
|
||||
import { RelayContext } from "@shared/relayProvider";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { parser } from "@utils/parser";
|
||||
import { useContext } from "react";
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { createNote, getNoteByID } from '@libs/storage';
|
||||
|
||||
import { RelayContext } from '@shared/relayProvider';
|
||||
|
||||
import { parser } from '@utils/parser';
|
||||
|
||||
export function useEvent(id: string) {
|
||||
const ndk = useContext(RelayContext);
|
||||
const { status, data, error, isFetching } = useQuery(
|
||||
["note", id],
|
||||
async () => {
|
||||
const result = await getNoteByID(id);
|
||||
if (result) {
|
||||
if (result.kind === 1 || result.kind === 1063) {
|
||||
result["content"] = parser(result);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
const event = await ndk.fetchEvent(id);
|
||||
await createNote(
|
||||
event.id,
|
||||
event.pubkey,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
event.created_at,
|
||||
);
|
||||
event["event_id"] = event.id;
|
||||
if (event.kind === 1 || event.kind === 1063) {
|
||||
// @ts-ignore
|
||||
event["content"] = parser(event);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
},
|
||||
);
|
||||
const ndk = useContext(RelayContext);
|
||||
const { status, data, error, isFetching } = useQuery(
|
||||
['note', id],
|
||||
async () => {
|
||||
const result = await getNoteByID(id);
|
||||
if (result) {
|
||||
if (result.kind === 1 || result.kind === 1063) {
|
||||
result['content'] = parser(result);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
const event = await ndk.fetchEvent(id);
|
||||
await createNote(
|
||||
event.id,
|
||||
event.pubkey,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
event.created_at
|
||||
);
|
||||
event['event_id'] = event.id;
|
||||
if (event.kind === 1 || event.kind === 1063) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
event['content'] = parser(event);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
}
|
||||
);
|
||||
|
||||
return { status, data, error, isFetching };
|
||||
return { status, data, error, isFetching };
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const getOnLineStatus = () =>
|
||||
typeof navigator !== "undefined" && typeof navigator.onLine === "boolean"
|
||||
? navigator.onLine
|
||||
: true;
|
||||
typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean'
|
||||
? navigator.onLine
|
||||
: true;
|
||||
|
||||
export function useNetworkStatus() {
|
||||
const [status, setStatus] = useState(getOnLineStatus());
|
||||
const [status, setStatus] = useState(getOnLineStatus());
|
||||
|
||||
const setOnline = () => setStatus(true);
|
||||
const setOffline = () => setStatus(false);
|
||||
const setOnline = () => setStatus(true);
|
||||
const setOffline = () => setStatus(false);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("online", setOnline);
|
||||
window.addEventListener("offline", setOffline);
|
||||
useEffect(() => {
|
||||
window.addEventListener('online', setOnline);
|
||||
window.addEventListener('offline', setOffline);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("online", setOnline);
|
||||
window.removeEventListener("offline", setOffline);
|
||||
};
|
||||
}, []);
|
||||
return () => {
|
||||
window.removeEventListener('online', setOnline);
|
||||
window.removeEventListener('offline', setOffline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import { getLinkPreview } from "@libs/openGraph";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { getLinkPreview } from '@libs/openGraph';
|
||||
|
||||
export function useOpenGraph(url: string) {
|
||||
const { status, data, error, isFetching } = useQuery(
|
||||
["preview", url],
|
||||
async () => {
|
||||
const res = await getLinkPreview(url);
|
||||
if (!res) {
|
||||
throw new Error("Can' fetch");
|
||||
}
|
||||
return res;
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
staleTime: Infinity,
|
||||
},
|
||||
);
|
||||
const { status, data, error, isFetching } = useQuery(
|
||||
['preview', url],
|
||||
async () => {
|
||||
const res = await getLinkPreview(url);
|
||||
if (!res) {
|
||||
throw new Error("Can' fetch");
|
||||
}
|
||||
return res;
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
staleTime: Infinity,
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
status,
|
||||
data,
|
||||
error,
|
||||
isFetching,
|
||||
};
|
||||
return {
|
||||
status,
|
||||
data,
|
||||
error,
|
||||
isFetching,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
import { NDKUser } from "@nostr-dev-kit/ndk";
|
||||
import { RelayContext } from "@shared/relayProvider";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useContext } from "react";
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { RelayContext } from '@shared/relayProvider';
|
||||
|
||||
export function useProfile(pubkey: string, fallback?: string) {
|
||||
const ndk = useContext(RelayContext);
|
||||
const {
|
||||
status,
|
||||
data: user,
|
||||
error,
|
||||
isFetching,
|
||||
} = useQuery(
|
||||
["user", pubkey],
|
||||
async () => {
|
||||
if (fallback) {
|
||||
const profile = JSON.parse(fallback);
|
||||
return profile;
|
||||
} else {
|
||||
const user = ndk.getUser({ hexpubkey: pubkey });
|
||||
await user.fetchProfile();
|
||||
const ndk = useContext(RelayContext);
|
||||
const {
|
||||
status,
|
||||
data: user,
|
||||
error,
|
||||
isFetching,
|
||||
} = useQuery(
|
||||
['user', pubkey],
|
||||
async () => {
|
||||
if (fallback) {
|
||||
const profile = JSON.parse(fallback);
|
||||
return profile;
|
||||
} else {
|
||||
const user = ndk.getUser({ hexpubkey: pubkey });
|
||||
await user.fetchProfile();
|
||||
|
||||
return user.profile;
|
||||
}
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
},
|
||||
);
|
||||
return user.profile;
|
||||
}
|
||||
},
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
}
|
||||
);
|
||||
|
||||
return { status, user, error, isFetching };
|
||||
return { status, user, error, isFetching };
|
||||
}
|
||||
|
||||
@@ -1,89 +1,93 @@
|
||||
import { useAccount } from "./useAccount";
|
||||
import { usePublish } from "@libs/ndk";
|
||||
import { createNote } from "@libs/storage";
|
||||
import { NDKEvent, NDKFilter } from "@nostr-dev-kit/ndk";
|
||||
import { RelayContext } from "@shared/relayProvider";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { dateToUnix, getHourAgo } from "@utils/date";
|
||||
import { nip02ToArray } from "@utils/transform";
|
||||
import { useContext } from "react";
|
||||
import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { usePublish } from '@libs/ndk';
|
||||
import { createNote } from '@libs/storage';
|
||||
|
||||
import { RelayContext } from '@shared/relayProvider';
|
||||
|
||||
import { dateToUnix, getHourAgo } from '@utils/date';
|
||||
import { nip02ToArray } from '@utils/transform';
|
||||
|
||||
import { useAccount } from './useAccount';
|
||||
|
||||
export function useSocial() {
|
||||
const ndk = useContext(RelayContext);
|
||||
const queryClient = useQueryClient();
|
||||
const publish = usePublish();
|
||||
const ndk = useContext(RelayContext);
|
||||
const queryClient = useQueryClient();
|
||||
const publish = usePublish();
|
||||
|
||||
const { account } = useAccount();
|
||||
const { status, data: userFollows } = useQuery(
|
||||
["userFollows", account.pubkey],
|
||||
async () => {
|
||||
const res = await ndk.fetchEvents({
|
||||
kinds: [3],
|
||||
authors: [account.pubkey],
|
||||
});
|
||||
const latest = [...res].slice(-1)[0];
|
||||
const list = nip02ToArray(latest.tags);
|
||||
return list;
|
||||
},
|
||||
{
|
||||
enabled: account ? true : false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
);
|
||||
const { account } = useAccount();
|
||||
const { status, data: userFollows } = useQuery(
|
||||
['userFollows', account.pubkey],
|
||||
async () => {
|
||||
const res = await ndk.fetchEvents({
|
||||
kinds: [3],
|
||||
authors: [account.pubkey],
|
||||
});
|
||||
const latest = [...res].slice(-1)[0];
|
||||
const list = nip02ToArray(latest.tags);
|
||||
return list;
|
||||
},
|
||||
{
|
||||
enabled: account ? true : false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
}
|
||||
);
|
||||
|
||||
const unfollow = (pubkey: string) => {
|
||||
const followsAsSet = new Set(userFollows);
|
||||
followsAsSet.delete(pubkey);
|
||||
const unfollow = (pubkey: string) => {
|
||||
const followsAsSet = new Set(userFollows);
|
||||
followsAsSet.delete(pubkey);
|
||||
|
||||
const tags = [];
|
||||
followsAsSet.forEach((item) => {
|
||||
tags.push(["p", item]);
|
||||
});
|
||||
const tags = [];
|
||||
followsAsSet.forEach((item) => {
|
||||
tags.push(['p', item]);
|
||||
});
|
||||
|
||||
// publish event
|
||||
publish({ content: "", kind: 3, tags: tags });
|
||||
// invalid cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["userFollows", account.pubkey],
|
||||
});
|
||||
};
|
||||
// publish event
|
||||
publish({ content: '', kind: 3, tags: tags });
|
||||
// invalid cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['userFollows', account.pubkey],
|
||||
});
|
||||
};
|
||||
|
||||
const follow = async (pubkey: string) => {
|
||||
const followsAsSet = new Set(userFollows);
|
||||
followsAsSet.add(pubkey);
|
||||
const follow = async (pubkey: string) => {
|
||||
const followsAsSet = new Set(userFollows);
|
||||
followsAsSet.add(pubkey);
|
||||
|
||||
const tags = [];
|
||||
followsAsSet.forEach((item) => {
|
||||
tags.push(["p", item]);
|
||||
});
|
||||
const tags = [];
|
||||
followsAsSet.forEach((item) => {
|
||||
tags.push(['p', item]);
|
||||
});
|
||||
|
||||
// publish event
|
||||
publish({ content: "", kind: 3, tags: tags });
|
||||
// invalid cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["userFollows", account.pubkey],
|
||||
});
|
||||
// publish event
|
||||
publish({ content: '', kind: 3, tags: tags });
|
||||
// invalid cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['userFollows', account.pubkey],
|
||||
});
|
||||
|
||||
// fetch events
|
||||
const filter: NDKFilter = {
|
||||
authors: [pubkey],
|
||||
kinds: [1, 6],
|
||||
since: dateToUnix(getHourAgo(48, new Date())),
|
||||
};
|
||||
const events = await ndk.fetchEvents(filter);
|
||||
events.forEach((event: NDKEvent) => {
|
||||
createNote(
|
||||
event.id,
|
||||
event.pubkey,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
event.created_at,
|
||||
);
|
||||
});
|
||||
};
|
||||
// fetch events
|
||||
const filter: NDKFilter = {
|
||||
authors: [pubkey],
|
||||
kinds: [1, 6],
|
||||
since: dateToUnix(getHourAgo(48, new Date())),
|
||||
};
|
||||
const events = await ndk.fetchEvents(filter);
|
||||
events.forEach((event: NDKEvent) => {
|
||||
createNote(
|
||||
event.id,
|
||||
event.pubkey,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
event.created_at
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
return { status, userFollows, follow, unfollow };
|
||||
return { status, userFollows, follow, unfollow };
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import {
|
||||
isPermissionGranted,
|
||||
requestPermission,
|
||||
sendNotification,
|
||||
} from "@tauri-apps/api/notification";
|
||||
isPermissionGranted,
|
||||
requestPermission,
|
||||
sendNotification,
|
||||
} from '@tauri-apps/api/notification';
|
||||
|
||||
export async function sendNativeNotification(content: string) {
|
||||
let permissionGranted = await isPermissionGranted();
|
||||
if (!permissionGranted) {
|
||||
const permission = await requestPermission();
|
||||
permissionGranted = permission === "granted";
|
||||
}
|
||||
if (permissionGranted) {
|
||||
sendNotification({ title: "Lume", body: content });
|
||||
}
|
||||
let permissionGranted = await isPermissionGranted();
|
||||
if (!permissionGranted) {
|
||||
const permission = await requestPermission();
|
||||
permissionGranted = permission === 'granted';
|
||||
}
|
||||
if (permissionGranted) {
|
||||
sendNotification({ title: 'Lume', body: content });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// convert number to K, M, B, T, etc.
|
||||
export const compactNumber = Intl.NumberFormat("en", { notation: "compact" });
|
||||
export const compactNumber = Intl.NumberFormat('en', { notation: 'compact' });
|
||||
|
||||
@@ -1,122 +1,115 @@
|
||||
import { MentionUser } from "@shared/notes/mentions/user";
|
||||
import destr from "destr";
|
||||
import getUrls from "get-urls";
|
||||
import { parseReferences } from "nostr-tools";
|
||||
import { ReactNode } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import reactStringReplace from "react-string-replace";
|
||||
import destr from 'destr';
|
||||
import getUrls from 'get-urls';
|
||||
import { parseReferences } from 'nostr-tools';
|
||||
import { ReactNode } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
|
||||
import { MentionUser } from '@shared/notes/mentions/user';
|
||||
|
||||
function isJsonString(str: string) {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
try {
|
||||
JSON.parse(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function parser(event: any) {
|
||||
if (isJsonString(event.tags)) {
|
||||
event["tags"] = destr(event.tags);
|
||||
}
|
||||
if (isJsonString(event.tags)) {
|
||||
event['tags'] = destr(event.tags);
|
||||
}
|
||||
|
||||
const references = parseReferences(event);
|
||||
const urls = getUrls(event.content);
|
||||
const references = parseReferences(event);
|
||||
const urls = getUrls(event.content);
|
||||
|
||||
const content: {
|
||||
original: string;
|
||||
parsed: ReactNode[];
|
||||
notes: string[];
|
||||
images: string[];
|
||||
videos: string[];
|
||||
links: string[];
|
||||
} = {
|
||||
original: event.content,
|
||||
parsed: event.content,
|
||||
notes: [],
|
||||
images: [],
|
||||
videos: [],
|
||||
links: [],
|
||||
};
|
||||
const content: {
|
||||
original: string;
|
||||
parsed: ReactNode[];
|
||||
notes: string[];
|
||||
images: string[];
|
||||
videos: string[];
|
||||
links: string[];
|
||||
} = {
|
||||
original: event.content,
|
||||
parsed: event.content,
|
||||
notes: [],
|
||||
images: [],
|
||||
videos: [],
|
||||
links: [],
|
||||
};
|
||||
|
||||
// remove unnecessary whitespaces
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/\s{2,}/g, " ");
|
||||
// remove unnecessary whitespaces
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/\s{2,}/g, ' ');
|
||||
|
||||
// remove unnecessary linebreak
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/(\r\n|\r|\n){2,}/g, "$1\n");
|
||||
// remove unnecessary linebreak
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
|
||||
|
||||
// parse urls
|
||||
urls?.forEach((url: string) => {
|
||||
if (url.match(/\.(jpg|jpeg|gif|png|webp|avif)$/)) {
|
||||
// image url
|
||||
content.images.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else if (url.match(/\.(mp4|webm|mov|ogv|avi|mp3)$/)) {
|
||||
// video
|
||||
content.videos.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else {
|
||||
if (content.links.length < 1) {
|
||||
// push to store
|
||||
content.links.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else {
|
||||
content.parsed = reactStringReplace(
|
||||
content.parsed,
|
||||
/#(\w+)/g,
|
||||
(match, i) => (
|
||||
<Link
|
||||
key={match + i}
|
||||
to={match}
|
||||
className="text-fuchsia-500 hover:text-fuchsia-600 no-underline font-normal"
|
||||
>
|
||||
{match}
|
||||
</Link>
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
// parse urls
|
||||
urls?.forEach((url: string) => {
|
||||
if (url.match(/\.(jpg|jpeg|gif|png|webp|avif)$/)) {
|
||||
// image url
|
||||
content.images.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else if (url.match(/\.(mp4|webm|mov|ogv|avi|mp3)$/)) {
|
||||
// video
|
||||
content.videos.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else {
|
||||
if (content.links.length < 1) {
|
||||
// push to store
|
||||
content.links.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
} else {
|
||||
content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
|
||||
<Link
|
||||
key={match + i}
|
||||
to={match}
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
>
|
||||
{match}
|
||||
</Link>
|
||||
));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// parse nostr
|
||||
references?.forEach((item) => {
|
||||
const profile = item.profile;
|
||||
const event = item.event;
|
||||
if (event) {
|
||||
content.notes.push(event.id);
|
||||
content.parsed = reactStringReplace(
|
||||
content.parsed,
|
||||
item.text,
|
||||
() => null,
|
||||
);
|
||||
}
|
||||
if (profile) {
|
||||
content.parsed = reactStringReplace(
|
||||
content.parsed,
|
||||
item.text,
|
||||
(match, i) => <MentionUser key={match + i} pubkey={profile.pubkey} />,
|
||||
);
|
||||
}
|
||||
});
|
||||
// parse nostr
|
||||
references?.forEach((item) => {
|
||||
const profile = item.profile;
|
||||
const event = item.event;
|
||||
if (event) {
|
||||
content.notes.push(event.id);
|
||||
content.parsed = reactStringReplace(content.parsed, item.text, () => null);
|
||||
}
|
||||
if (profile) {
|
||||
content.parsed = reactStringReplace(content.parsed, item.text, (match, i) => (
|
||||
<MentionUser key={match + i} pubkey={profile.pubkey} />
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
// parse hashtag
|
||||
content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
|
||||
<Link
|
||||
key={match + i}
|
||||
to={`/search/${match}`}
|
||||
className="text-fuchsia-500 hover:text-fuchsia-600 no-underline font-normal"
|
||||
>
|
||||
#{match}
|
||||
</Link>
|
||||
));
|
||||
// parse hashtag
|
||||
content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
|
||||
<Link
|
||||
key={match + i}
|
||||
to={`/search/${match}`}
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
>
|
||||
#{match}
|
||||
</Link>
|
||||
));
|
||||
|
||||
// clean array
|
||||
content.parsed = content.parsed.filter((el) => el !== "\n");
|
||||
// clean array
|
||||
content.parsed = content.parsed.filter((el) => el !== '\n');
|
||||
|
||||
return content;
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { nip19 } from 'nostr-tools';
|
||||
|
||||
export function shortenKey(pubkey: string) {
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
return npub.substring(0, 16).concat("...");
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
return npub.substring(0, 16).concat('...');
|
||||
}
|
||||
|
||||
@@ -1,105 +1,105 @@
|
||||
import { NDKTag } from "@nostr-dev-kit/ndk";
|
||||
import destr from "destr";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { NDKTag } from '@nostr-dev-kit/ndk';
|
||||
import destr from 'destr';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
|
||||
export function truncateContent(str, n) {
|
||||
return str.length > n ? `${str.slice(0, n - 1)}...` : str;
|
||||
return str.length > n ? `${str.slice(0, n - 1)}...` : str;
|
||||
}
|
||||
|
||||
export function setToArray(tags: any) {
|
||||
const newArray = [];
|
||||
tags.forEach((item) => {
|
||||
const hexpubkey = nip19.decode(item.npub).data;
|
||||
newArray.push(hexpubkey);
|
||||
});
|
||||
const newArray = [];
|
||||
tags.forEach((item) => {
|
||||
const hexpubkey = nip19.decode(item.npub).data;
|
||||
newArray.push(hexpubkey);
|
||||
});
|
||||
|
||||
return newArray;
|
||||
return newArray;
|
||||
}
|
||||
|
||||
// convert NIP-02 to array of pubkey
|
||||
export function nip02ToArray(tags: any) {
|
||||
const arr = [];
|
||||
tags.forEach((item) => {
|
||||
arr.push(item[1]);
|
||||
});
|
||||
const arr = [];
|
||||
tags.forEach((item) => {
|
||||
arr.push(item[1]);
|
||||
});
|
||||
|
||||
return arr;
|
||||
return arr;
|
||||
}
|
||||
|
||||
// convert array to NIP-02 tag list
|
||||
export function arrayToNIP02(arr: string[]) {
|
||||
const nip02_arr = [];
|
||||
arr.forEach((item) => {
|
||||
nip02_arr.push(["p", item]);
|
||||
});
|
||||
const nip02_arr = [];
|
||||
arr.forEach((item) => {
|
||||
nip02_arr.push(['p', item]);
|
||||
});
|
||||
|
||||
return nip02_arr;
|
||||
return nip02_arr;
|
||||
}
|
||||
|
||||
// convert array object to pure array
|
||||
export function arrayObjToPureArr(arr: any) {
|
||||
const pure_arr = [];
|
||||
arr.forEach((item) => {
|
||||
pure_arr.push(item.content);
|
||||
});
|
||||
const pure_arr = [];
|
||||
arr.forEach((item) => {
|
||||
pure_arr.push(item.content);
|
||||
});
|
||||
|
||||
return pure_arr;
|
||||
return pure_arr;
|
||||
}
|
||||
|
||||
// get parent id from event tags
|
||||
export function getParentID(arr: string[], fallback: string) {
|
||||
const tags = destr(arr);
|
||||
let parentID = fallback;
|
||||
const tags = destr(arr);
|
||||
let parentID = fallback;
|
||||
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][0] === "e") {
|
||||
parentID = tags[0][1];
|
||||
} else {
|
||||
tags.forEach((tag) => {
|
||||
if (tag[0] === "e" && (tag[2] === "root" || tag[3] === "root")) {
|
||||
parentID = tag[1];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][0] === 'e') {
|
||||
parentID = tags[0][1];
|
||||
} else {
|
||||
tags.forEach((tag) => {
|
||||
if (tag[0] === 'e' && (tag[2] === 'root' || tag[3] === 'root')) {
|
||||
parentID = tag[1];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return parentID;
|
||||
return parentID;
|
||||
}
|
||||
|
||||
// check id present in event tags
|
||||
export function isTagsIncludeID(id: string, arr: NDKTag[]) {
|
||||
const tags = destr(arr);
|
||||
const tags = destr(arr);
|
||||
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][1] === id) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][1] === id) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get parent id from event tags
|
||||
export function getRepostID(arr: NDKTag[]) {
|
||||
const tags = destr(arr);
|
||||
let quoteID = null;
|
||||
const tags = destr(arr);
|
||||
let quoteID = null;
|
||||
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][0] === "e") {
|
||||
quoteID = tags[0][1];
|
||||
} else {
|
||||
quoteID = tags.find((t) => t[0] === "e")?.[1];
|
||||
}
|
||||
}
|
||||
if (tags.length > 0) {
|
||||
if (tags[0][0] === 'e') {
|
||||
quoteID = tags[0][1];
|
||||
} else {
|
||||
quoteID = tags.find((t) => t[0] === 'e')?.[1];
|
||||
}
|
||||
}
|
||||
|
||||
return quoteID;
|
||||
return quoteID;
|
||||
}
|
||||
|
||||
// sort events by timestamp
|
||||
export function sortEvents(arr: any) {
|
||||
arr.sort((a, b) => {
|
||||
return a.created_at - b.created_at;
|
||||
});
|
||||
arr.sort((a, b) => {
|
||||
return a.created_at - b.created_at;
|
||||
});
|
||||
|
||||
return arr;
|
||||
return arr;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
|
||||
export interface LumeEvent extends NDKEvent {
|
||||
event_id: string;
|
||||
parent_id: string;
|
||||
event_id: string;
|
||||
parent_id: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user