Make Lume Faster (#208)

* chore: fix some lint issues

* feat: refactor contact list

* feat: refactor relay hint

* feat: add missing commands

* feat: use new cache layer for react query

* feat: refactor column

* feat: improve relay hint

* fix: replace break with continue in parser

* refactor: publish function

* feat: add reply command

* feat: improve editor

* fix: quote

* chore: update deps

* refactor: note component

* feat: improve repost

* feat: improve cache

* fix: backup screen

* refactor: column manager
This commit is contained in:
雨宮蓮
2024-06-17 13:52:06 +07:00
committed by GitHub
parent 7c99ed39e4
commit 843895d876
79 changed files with 1738 additions and 1975 deletions

View File

@@ -1,6 +1,11 @@
import type { EventWithReplies, Kind, Meta, NostrEvent } from "@lume/types";
import { commands } from "./commands";
import { generateContentTags } from "@lume/utils";
import type {
EventTag,
EventWithReplies,
Kind,
Meta,
NostrEvent,
} from "@lume/types";
import { type Result, commands } from "./commands";
export class LumeEvent {
public id: string;
@@ -10,8 +15,8 @@ export class LumeEvent {
public tags: string[][];
public content: string;
public sig: string;
public relay?: string;
public meta: Meta;
public relay?: string;
#raw: NostrEvent;
constructor(event: NostrEvent) {
@@ -19,49 +24,52 @@ export class LumeEvent {
Object.assign(this, event);
}
get isQuote() {
return this.tags.filter((tag) => tag[0] === "q").length > 0;
}
get isConversation() {
const tags = this.tags.filter(
(tag) => tag[0] === "e" && tag[3] !== "mention",
);
return tags.length > 0;
}
get mentions() {
return this.tags.filter((tag) => tag[0] === "p").map((tag) => tag[1]);
}
static getEventThread(tags: string[][], gossip = true) {
let root: string = null;
let reply: string = null;
get repostId() {
return this.tags.find((tag) => tag[0] === "e")[1];
}
// Get all event references from tags, ignore mention
const events = tags.filter((el) => el[0] === "e" && el[3] !== "mention");
get thread() {
let root: EventTag = null;
let reply: EventTag = null;
if (gossip) {
const relays = tags
.filter((el) => el[0] === "e" && el[2]?.length)
.map((tag) => tag[2]);
// Get all event references from tags, ignore mention.
const events = this.tags.filter(
(el) => el[0] === "e" && el[3] !== "mention",
);
if (relays.length >= 1) {
for (const relay of relays) {
try {
if (relay.length) {
const url = new URL(relay);
commands
.connectRelay(url.toString())
.then(() => console.log("[relay hint]: ", url));
}
} catch (e) {
console.log("[relay hint] error: ", relay);
}
}
if (events.length === 1) {
root = { id: events[0][1], relayHint: events[0][2] };
}
if (events.length === 2) {
root = { id: events[0][1], relayHint: events[0][2] };
reply = { id: events[1][1], relayHint: events[1][2] };
}
if (events.length > 2) {
for (const tag of events) {
if (tag[3] === "root") root = { id: tag[1], relayHint: tag[2] };
if (tag[3] === "reply") reply = { id: tag[1], relayHint: tag[2] };
}
}
if (events.length === 1) {
root = events[0][1];
}
if (events.length > 1) {
root = events.find((el) => el[3] === "root")?.[1] ?? events[0][1];
reply = events.find((el) => el[3] === "reply")?.[1] ?? events[1][1];
}
// Fix some rare case when root === reply
if (root && reply && root === reply) {
// Fix some rare case when root same as reply
if (root && reply && root.id === reply.id) {
reply = null;
}
@@ -71,7 +79,17 @@ export class LumeEvent {
};
}
static async getReplies(id: string) {
get quote() {
const tag = this.tags.filter(
(tag) => tag[0] === "q" || tag[3] === "mention",
);
const id = tag[0][1];
const relayHint = tag[0][2];
return { id, relayHint };
}
public async getReplies(id: string) {
const query = await commands.getReplies(id);
if (query.status === "ok") {
@@ -99,14 +117,6 @@ export class LumeEvent {
for (const tag of tags) {
const rootIndex = events.findIndex((el) => el.id === tag[1]);
// Relay Hint
if (tag[2]?.length) {
const url = new URL(tag[2]);
commands
.connectRelay(url.toString())
.then(() => console.log("[relay hint]: ", url));
}
if (rootIndex !== -1) {
const rootEvent = events[rootIndex];
@@ -129,63 +139,8 @@ export class LumeEvent {
}
}
static async publish(
content: string,
reply_to?: string,
quote?: boolean,
nsfw?: boolean,
) {
const g = await generateContentTags(content);
const eventContent = g.content;
const eventTags = g.tags;
if (reply_to) {
const queryReply = await commands.getEvent(reply_to);
if (queryReply.status === "ok") {
const replyEvent = JSON.parse(queryReply.data.raw) as NostrEvent;
const relayHint =
replyEvent.tags.find((ev) => ev[0] === "e")?.[0][2] ?? "";
if (quote) {
eventTags.push(["e", replyEvent.id, relayHint, "mention"]);
eventTags.push(["q", replyEvent.id]);
} else {
const rootEvent = replyEvent.tags.find((ev) => ev[3] === "root");
if (rootEvent) {
eventTags.push([
"e",
rootEvent[1],
rootEvent[2] || relayHint,
"root",
]);
}
eventTags.push(["e", replyEvent.id, relayHint, "reply"]);
eventTags.push(["p", replyEvent.pubkey]);
}
}
}
if (nsfw) {
eventTags.push(["L", "content-warning"]);
eventTags.push(["l", "reason", "content-warning"]);
eventTags.push(["content-warning", "nsfw"]);
}
const query = await commands.publish(eventContent, eventTags);
if (query.status === "ok") {
return query.data;
} else {
throw new Error(query.error);
}
}
static async zap(id: string, amount: number, message: string) {
const query = await commands.zapEvent(id, amount.toString(), message);
public async zap(amount: number, message: string) {
const query = await commands.zapEvent(this.id, amount.toString(), message);
if (query.status === "ok") {
return query.data;
@@ -223,4 +178,26 @@ export class LumeEvent {
throw new Error(query.error);
}
}
static async publish(
content: string,
warning?: string,
difficulty?: number,
reply_to?: string,
root_to?: string,
) {
let query: Result<string, string>;
if (reply_to) {
query = await commands.reply(content, reply_to, root_to);
} else {
query = await commands.publish(content, warning, difficulty);
}
if (query.status === "ok") {
return query.data;
} else {
throw new Error(query.error);
}
}
}