rome -> eslint + prettier

This commit is contained in:
Ren Amamiya
2023-07-04 13:24:42 +07:00
parent 744fbd5683
commit a30cf66c2e
187 changed files with 10179 additions and 10066 deletions

View File

@@ -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]);
}

View 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;
}

View File

@@ -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);
}

View File

@@ -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 };
}

View File

@@ -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 };
}

View File

@@ -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;
}

View File

@@ -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,
};
}

View File

@@ -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 };
}

View File

@@ -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 };
}

View File

@@ -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 });
}
}

View File

@@ -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' });

View File

@@ -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;
}

View File

@@ -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('...');
}

View File

@@ -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;
}

View File

@@ -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;
}