feat: improve tauri commands
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { Conversation } from "@/components/conversation";
|
||||||
|
import { Quote } from "@/components/quote";
|
||||||
import { RepostNote } from "@/components/repost";
|
import { RepostNote } from "@/components/repost";
|
||||||
import { TextNote } from "@/components/text";
|
import { TextNote } from "@/components/text";
|
||||||
import { ArrowRightCircleIcon, ArrowRightIcon } from "@lume/icons";
|
import { ArrowRightCircleIcon, ArrowRightIcon } from "@lume/icons";
|
||||||
@@ -39,7 +41,7 @@ export const Route = createFileRoute("/foryou")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function Screen() {
|
export function Screen() {
|
||||||
const { name, account } = Route.useSearch();
|
const { label, account } = Route.useSearch();
|
||||||
const { ark, interests } = Route.useRouteContext();
|
const { ark, interests } = Route.useRouteContext();
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
@@ -49,20 +51,17 @@ export function Screen() {
|
|||||||
hasNextPage,
|
hasNextPage,
|
||||||
fetchNextPage,
|
fetchNextPage,
|
||||||
} = useInfiniteQuery({
|
} = useInfiniteQuery({
|
||||||
queryKey: [name, account],
|
queryKey: [label, account],
|
||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const events = await ark.get_events_from_interests(
|
const events = await ark.get_hashtag_events(
|
||||||
interests.hashtags,
|
interests.hashtags,
|
||||||
20,
|
20,
|
||||||
pageParam,
|
pageParam,
|
||||||
);
|
);
|
||||||
return events;
|
return events;
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => {
|
getNextPageParam: (lastPage) => lastPage?.at(-1)?.created_at - 1,
|
||||||
const lastEvent = lastPage?.at(-1);
|
|
||||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
|
||||||
},
|
|
||||||
select: (data) => data?.pages.flatMap((page) => page),
|
select: (data) => data?.pages.flatMap((page) => page),
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
});
|
});
|
||||||
@@ -72,8 +71,22 @@ export function Screen() {
|
|||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case Kind.Repost:
|
case Kind.Repost:
|
||||||
return <RepostNote key={event.id} event={event} />;
|
return <RepostNote key={event.id} event={event} />;
|
||||||
default:
|
default: {
|
||||||
return <TextNote key={event.id} event={event} />;
|
const isConversation =
|
||||||
|
event.tags.filter((tag) => tag[0] === "e" && tag[3] !== "mention")
|
||||||
|
.length > 0;
|
||||||
|
const isQuote = event.tags.filter((tag) => tag[0] === "q").length > 0;
|
||||||
|
|
||||||
|
if (isConversation) {
|
||||||
|
return <Conversation key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isQuote) {
|
||||||
|
return <Quote key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <TextNote key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const Route = createFileRoute("/global")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function Screen() {
|
export function Screen() {
|
||||||
const { account } = Route.useSearch();
|
const { label, account } = Route.useSearch();
|
||||||
const { ark } = Route.useRouteContext();
|
const { ark } = Route.useRouteContext();
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
@@ -37,16 +37,13 @@ export function Screen() {
|
|||||||
hasNextPage,
|
hasNextPage,
|
||||||
fetchNextPage,
|
fetchNextPage,
|
||||||
} = useInfiniteQuery({
|
} = useInfiniteQuery({
|
||||||
queryKey: ["global", account],
|
queryKey: [label, account],
|
||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const events = await ark.get_events(20, pageParam, undefined, true);
|
const events = await ark.get_global_events(20, pageParam);
|
||||||
return events;
|
return events;
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => {
|
getNextPageParam: (lastPage) => lastPage?.at(-1)?.created_at - 1,
|
||||||
const lastEvent = lastPage?.at(-1);
|
|
||||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
|
||||||
},
|
|
||||||
select: (data) => data?.pages.flatMap((page) => page),
|
select: (data) => data?.pages.flatMap((page) => page),
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Conversation } from "@/components/conversation";
|
||||||
|
import { Quote } from "@/components/quote";
|
||||||
import { RepostNote } from "@/components/repost";
|
import { RepostNote } from "@/components/repost";
|
||||||
import { TextNote } from "@/components/text";
|
import { TextNote } from "@/components/text";
|
||||||
import { ArrowRightCircleIcon, ArrowRightIcon } from "@lume/icons";
|
import { ArrowRightCircleIcon, ArrowRightIcon } from "@lume/icons";
|
||||||
@@ -41,7 +43,7 @@ export const Route = createFileRoute("/group")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function Screen() {
|
export function Screen() {
|
||||||
const { name, account } = Route.useSearch();
|
const { label, account } = Route.useSearch();
|
||||||
const { ark, groups } = Route.useRouteContext();
|
const { ark, groups } = Route.useRouteContext();
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
@@ -51,16 +53,13 @@ export function Screen() {
|
|||||||
hasNextPage,
|
hasNextPage,
|
||||||
fetchNextPage,
|
fetchNextPage,
|
||||||
} = useInfiniteQuery({
|
} = useInfiniteQuery({
|
||||||
queryKey: [name, account],
|
queryKey: [label, account],
|
||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const events = await ark.get_events(20, pageParam, groups);
|
const events = await ark.get_group_events(groups, 20, pageParam);
|
||||||
return events;
|
return events;
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => {
|
getNextPageParam: (lastPage) => lastPage?.at(-1)?.created_at - 1,
|
||||||
const lastEvent = lastPage?.at(-1);
|
|
||||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
|
||||||
},
|
|
||||||
select: (data) =>
|
select: (data) =>
|
||||||
data?.pages.flatMap((page) => page.filter((ev) => ev.kind === Kind.Text)),
|
data?.pages.flatMap((page) => page.filter((ev) => ev.kind === Kind.Text)),
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
@@ -71,8 +70,22 @@ export function Screen() {
|
|||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case Kind.Repost:
|
case Kind.Repost:
|
||||||
return <RepostNote key={event.id} event={event} />;
|
return <RepostNote key={event.id} event={event} />;
|
||||||
default:
|
default: {
|
||||||
return <TextNote key={event.id} event={event} />;
|
const isConversation =
|
||||||
|
event.tags.filter((tag) => tag[0] === "e" && tag[3] !== "mention")
|
||||||
|
.length > 0;
|
||||||
|
const isQuote = event.tags.filter((tag) => tag[0] === "q").length > 0;
|
||||||
|
|
||||||
|
if (isConversation) {
|
||||||
|
return <Conversation key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isQuote) {
|
||||||
|
return <Quote key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <TextNote key={event.id} event={event} className="mb-3" />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,13 +41,10 @@ export function Screen() {
|
|||||||
queryKey: [label, account],
|
queryKey: [label, account],
|
||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const events = await ark.get_events(20, pageParam);
|
const events = await ark.get_local_events(20, pageParam);
|
||||||
return events;
|
return events;
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => {
|
getNextPageParam: (lastPage) => lastPage?.at(-1)?.created_at - 1,
|
||||||
const lastEvent = lastPage?.at(-1);
|
|
||||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
|
||||||
},
|
|
||||||
select: (data) => data?.pages.flatMap((page) => page),
|
select: (data) => data?.pages.flatMap((page) => page),
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
});
|
});
|
||||||
@@ -79,7 +76,7 @@ export function Screen() {
|
|||||||
return (
|
return (
|
||||||
<div className="p-2 w-full h-full overflow-y-auto scrollbar-none">
|
<div className="p-2 w-full h-full overflow-y-auto scrollbar-none">
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
<div className="w-full h-11 flex items-center justify-center">
|
<div className="w-full h-11 flex items-center justify-center bg-white dark:bg-black/20 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Spinner className="size-5" />
|
<Spinner className="size-5" />
|
||||||
<span className="text-sm font-medium">Fetching new notes...</span>
|
<span className="text-sm font-medium">Fetching new notes...</span>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const Route = createFileRoute("/users/$pubkey")({
|
|||||||
},
|
},
|
||||||
loader: async ({ params, context }) => {
|
loader: async ({ params, context }) => {
|
||||||
const ark = context.ark;
|
const ark = context.ark;
|
||||||
return { data: defer(ark.get_events_from(params.pubkey, 50)) };
|
return { data: defer(ark.get_events_by(params.pubkey, 50)) };
|
||||||
},
|
},
|
||||||
component: Screen,
|
component: Screen,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function EventList({ id }: { id: string }) {
|
|||||||
queryKey: ["events", id],
|
queryKey: ["events", id],
|
||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const events = await ark.get_events_from(id, FETCH_LIMIT, pageParam);
|
const events = await ark.get_events_by(id, FETCH_LIMIT, pageParam);
|
||||||
return events;
|
return events;
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => {
|
getNextPageParam: (lastPage) => {
|
||||||
|
|||||||
@@ -164,24 +164,6 @@ export class Ark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async get_events_from(pubkey: string, limit: number, asOf?: number) {
|
|
||||||
try {
|
|
||||||
let until: string = undefined;
|
|
||||||
if (asOf && asOf > 0) until = asOf.toString();
|
|
||||||
|
|
||||||
const nostrEvents: Event[] = await invoke("get_events_from", {
|
|
||||||
publicKey: pubkey,
|
|
||||||
limit,
|
|
||||||
as_of: until,
|
|
||||||
});
|
|
||||||
|
|
||||||
return nostrEvents.sort((a, b) => b.created_at - a.created_at);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(String(e));
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async search(content: string, limit: number) {
|
public async search(content: string, limit: number) {
|
||||||
try {
|
try {
|
||||||
if (content.length < 1) return [];
|
if (content.length < 1) return [];
|
||||||
@@ -198,24 +180,8 @@ export class Ark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async get_events(
|
private dedup_events(nostrEvents: Event[]) {
|
||||||
limit: number,
|
|
||||||
asOf?: number,
|
|
||||||
contacts?: string[],
|
|
||||||
global?: boolean,
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
|
||||||
const isGlobal = global ?? false;
|
|
||||||
const seens = new Set<string>();
|
const seens = new Set<string>();
|
||||||
|
|
||||||
const nostrEvents: Event[] = await invoke("get_events", {
|
|
||||||
limit,
|
|
||||||
until,
|
|
||||||
contacts,
|
|
||||||
global: isGlobal,
|
|
||||||
});
|
|
||||||
|
|
||||||
const events = nostrEvents.filter((event) => {
|
const events = nostrEvents.filter((event) => {
|
||||||
const eTags = event.tags.filter((el) => el[0] === "e");
|
const eTags = event.tags.filter((el) => el[0] === "e");
|
||||||
const ids = eTags.map((item) => item[1]);
|
const ids = eTags.map((item) => item[1]);
|
||||||
@@ -238,50 +204,98 @@ export class Ark {
|
|||||||
return !isDup;
|
return !isDup;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async get_local_events(limit: number, asOf?: number) {
|
||||||
|
try {
|
||||||
|
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
||||||
|
const nostrEvents: Event[] = await invoke("get_local_events", {
|
||||||
|
limit,
|
||||||
|
until,
|
||||||
|
});
|
||||||
|
const events = this.dedup_events(nostrEvents);
|
||||||
|
|
||||||
return events;
|
return events;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[get_events] failed", String(e));
|
console.error("[get_local_events] failed", String(e));
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async get_events_from_interests(
|
public async get_global_events(limit: number, asOf?: number) {
|
||||||
|
try {
|
||||||
|
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
||||||
|
const nostrEvents: Event[] = await invoke("get_global_events", {
|
||||||
|
limit,
|
||||||
|
until,
|
||||||
|
});
|
||||||
|
const events = this.dedup_events(nostrEvents);
|
||||||
|
|
||||||
|
return events;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[get_global_events] failed", String(e));
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async get_hashtag_events(
|
||||||
hashtags: string[],
|
hashtags: string[],
|
||||||
limit: number,
|
limit: number,
|
||||||
asOf?: number,
|
asOf?: number,
|
||||||
) {
|
) {
|
||||||
let until: string = undefined;
|
try {
|
||||||
if (asOf && asOf > 0) until = asOf.toString();
|
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
||||||
|
const nostrTags = hashtags.map((tag) => tag.replace("#", ""));
|
||||||
const seenIds = new Set<string>();
|
const nostrEvents: Event[] = await invoke("get_hashtag_events", {
|
||||||
const dedupQueue = new Set<string>();
|
|
||||||
const nostrTags = hashtags.map((tag) => tag.replace("#", "").toLowerCase());
|
|
||||||
|
|
||||||
const nostrEvents: Event[] = await invoke("get_events_from_interests", {
|
|
||||||
hashtags: nostrTags,
|
hashtags: nostrTags,
|
||||||
limit,
|
limit,
|
||||||
until,
|
until,
|
||||||
});
|
});
|
||||||
|
const events = this.dedup_events(nostrEvents);
|
||||||
|
|
||||||
for (const event of nostrEvents) {
|
return events;
|
||||||
const tags = event.tags
|
} catch (e) {
|
||||||
.filter((el) => el[0] === "e")
|
console.error("[get_hashtag_events] failed", String(e));
|
||||||
?.map((item) => item[1]);
|
return [];
|
||||||
|
|
||||||
if (tags.length) {
|
|
||||||
for (const tag of tags) {
|
|
||||||
if (seenIds.has(tag)) {
|
|
||||||
dedupQueue.add(event.id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
seenIds.add(tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nostrEvents
|
public async get_group_events(
|
||||||
.filter((event) => !dedupQueue.has(event.id))
|
contacts: string[],
|
||||||
.sort((a, b) => b.created_at - a.created_at);
|
limit: number,
|
||||||
|
asOf?: number,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
||||||
|
const nostrEvents: Event[] = await invoke("get_group_events", {
|
||||||
|
list: contacts,
|
||||||
|
limit,
|
||||||
|
until,
|
||||||
|
});
|
||||||
|
const events = this.dedup_events(nostrEvents);
|
||||||
|
|
||||||
|
return events;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[get_group_events] failed", String(e));
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async get_events_by(pubkey: string, limit: number, asOf?: number) {
|
||||||
|
try {
|
||||||
|
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
|
||||||
|
const nostrEvents: Event[] = await invoke("get_events_by", {
|
||||||
|
publicKey: pubkey,
|
||||||
|
limit,
|
||||||
|
as_of: until,
|
||||||
|
});
|
||||||
|
|
||||||
|
return nostrEvents.sort((a, b) => b.created_at - a.created_at);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[get_events_by] failed", String(e));
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async publish(
|
public async publish(
|
||||||
@@ -356,27 +370,9 @@ export class Ark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async upvote(id: string, author: string) {
|
|
||||||
try {
|
|
||||||
const cmd: string = await invoke("upvote", { id, pubkey: author });
|
|
||||||
return cmd;
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(String(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async downvote(id: string, author: string) {
|
|
||||||
try {
|
|
||||||
const cmd: string = await invoke("downvote", { id, pubkey: author });
|
|
||||||
return cmd;
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(String(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async get_event_thread(id: string) {
|
public async get_event_thread(id: string) {
|
||||||
try {
|
try {
|
||||||
const events: EventWithReplies[] = await invoke("get_event_thread", {
|
const events: EventWithReplies[] = await invoke("get_thread", {
|
||||||
id,
|
id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -127,10 +127,12 @@ fn main() {
|
|||||||
nostr::metadata::zap_event,
|
nostr::metadata::zap_event,
|
||||||
nostr::metadata::friend_to_friend,
|
nostr::metadata::friend_to_friend,
|
||||||
nostr::event::get_event,
|
nostr::event::get_event,
|
||||||
nostr::event::get_events_from,
|
nostr::event::get_thread,
|
||||||
nostr::event::get_events,
|
nostr::event::get_events_by,
|
||||||
nostr::event::get_events_from_interests,
|
nostr::event::get_local_events,
|
||||||
nostr::event::get_event_thread,
|
nostr::event::get_global_events,
|
||||||
|
nostr::event::get_hashtag_events,
|
||||||
|
nostr::event::get_group_events,
|
||||||
nostr::event::publish,
|
nostr::event::publish,
|
||||||
nostr::event::repost,
|
nostr::event::repost,
|
||||||
commands::folder::show_in_folder,
|
commands::folder::show_in_folder,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result<String, Stri
|
|||||||
Some(id) => {
|
Some(id) => {
|
||||||
let filter = Filter::new().id(id);
|
let filter = Filter::new().id(id);
|
||||||
|
|
||||||
match &client
|
match client
|
||||||
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,24 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result<String, Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_events_from(
|
pub async fn get_thread(id: &str, state: State<'_, Nostr>) -> Result<Vec<Event>, String> {
|
||||||
|
let client = &state.client;
|
||||||
|
|
||||||
|
match EventId::from_hex(id) {
|
||||||
|
Ok(event_id) => {
|
||||||
|
let filter = Filter::new().kinds(vec![Kind::TextNote]).event(event_id);
|
||||||
|
|
||||||
|
match client.get_events_of(vec![filter], None).await {
|
||||||
|
Ok(events) => Ok(events),
|
||||||
|
Err(err) => Err(err.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => Err("Event ID is not valid".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_events_by(
|
||||||
public_key: &str,
|
public_key: &str,
|
||||||
limit: usize,
|
limit: usize,
|
||||||
as_of: Option<&str>,
|
as_of: Option<&str>,
|
||||||
@@ -57,7 +74,8 @@ pub async fn get_events_from(
|
|||||||
) -> Result<Vec<Event>, String> {
|
) -> Result<Vec<Event>, String> {
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
|
|
||||||
if let Ok(author) = PublicKey::from_str(public_key) {
|
match PublicKey::from_str(public_key) {
|
||||||
|
Ok(author) => {
|
||||||
let until = match as_of {
|
let until = match as_of {
|
||||||
Some(until) => Timestamp::from_str(until).unwrap(),
|
Some(until) => Timestamp::from_str(until).unwrap(),
|
||||||
None => Timestamp::now(),
|
None => Timestamp::now(),
|
||||||
@@ -72,17 +90,15 @@ pub async fn get_events_from(
|
|||||||
Ok(events) => Ok(events),
|
Ok(events) => Ok(events),
|
||||||
Err(err) => Err(err.to_string()),
|
Err(err) => Err(err.to_string()),
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
Err("Public Key is not valid, please check again.".into())
|
Err(err) => Err(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_events(
|
pub async fn get_local_events(
|
||||||
limit: usize,
|
limit: usize,
|
||||||
until: Option<&str>,
|
until: Option<&str>,
|
||||||
contacts: Option<Vec<&str>>,
|
|
||||||
global: bool,
|
|
||||||
state: State<'_, Nostr>,
|
state: State<'_, Nostr>,
|
||||||
) -> Result<Vec<Event>, String> {
|
) -> Result<Vec<Event>, String> {
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
@@ -91,66 +107,57 @@ pub async fn get_events(
|
|||||||
None => Timestamp::now(),
|
None => Timestamp::now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match global {
|
|
||||||
true => {
|
|
||||||
let filter = Filter::new()
|
|
||||||
.kinds(vec![Kind::TextNote, Kind::Repost])
|
|
||||||
.limit(limit)
|
|
||||||
.until(as_of);
|
|
||||||
|
|
||||||
match client
|
|
||||||
.get_events_of(vec![filter], Some(Duration::from_secs(15)))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(events) => Ok(events),
|
|
||||||
Err(err) => Err(err.to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false => {
|
|
||||||
let authors = match contacts {
|
|
||||||
Some(val) => {
|
|
||||||
let c: Vec<PublicKey> = val
|
|
||||||
.into_iter()
|
|
||||||
.map(|key| PublicKey::from_str(key).unwrap())
|
|
||||||
.collect();
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
match client
|
match client
|
||||||
.get_contact_list_public_keys(Some(Duration::from_secs(10)))
|
.get_contact_list_public_keys(Some(Duration::from_secs(10)))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(val) => Some(val),
|
Ok(contacts) => {
|
||||||
Err(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match authors {
|
|
||||||
Some(val) => {
|
|
||||||
if val.is_empty() {
|
|
||||||
Err("Get local events but contact list is empty".into())
|
|
||||||
} else {
|
|
||||||
let filter = Filter::new()
|
let filter = Filter::new()
|
||||||
.kinds(vec![Kind::TextNote, Kind::Repost])
|
.kinds(vec![Kind::TextNote, Kind::Repost])
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.authors(val.clone())
|
.authors(contacts)
|
||||||
.until(as_of);
|
.until(as_of);
|
||||||
|
|
||||||
match client.get_events_of(vec![filter], None).await {
|
match client
|
||||||
|
.get_events_of(vec![filter], Some(Duration::from_secs(8)))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(events) => Ok(events),
|
Ok(events) => Ok(events),
|
||||||
Err(err) => Err(err.to_string()),
|
Err(err) => Err(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(err) => Err(err.to_string()),
|
||||||
None => Err("Get local events but contact list is empty".into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_events_from_interests(
|
pub async fn get_global_events(
|
||||||
|
limit: usize,
|
||||||
|
until: Option<&str>,
|
||||||
|
state: State<'_, Nostr>,
|
||||||
|
) -> Result<Vec<Event>, String> {
|
||||||
|
let client = &state.client;
|
||||||
|
let as_of = match until {
|
||||||
|
Some(until) => Timestamp::from_str(until).unwrap(),
|
||||||
|
None => Timestamp::now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kinds(vec![Kind::TextNote, Kind::Repost])
|
||||||
|
.limit(limit)
|
||||||
|
.until(as_of);
|
||||||
|
|
||||||
|
match client
|
||||||
|
.get_events_of(vec![filter], Some(Duration::from_secs(8)))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(events) => Ok(events),
|
||||||
|
Err(err) => Err(err.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_hashtag_events(
|
||||||
hashtags: Vec<&str>,
|
hashtags: Vec<&str>,
|
||||||
limit: usize,
|
limit: usize,
|
||||||
until: Option<&str>,
|
until: Option<&str>,
|
||||||
@@ -174,20 +181,31 @@ pub async fn get_events_from_interests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_event_thread(id: &str, state: State<'_, Nostr>) -> Result<Vec<Event>, String> {
|
pub async fn get_group_events(
|
||||||
|
list: Vec<&str>,
|
||||||
|
limit: usize,
|
||||||
|
until: Option<&str>,
|
||||||
|
state: State<'_, Nostr>,
|
||||||
|
) -> Result<Vec<Event>, String> {
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
|
let as_of = match until {
|
||||||
match EventId::from_hex(id) {
|
Some(until) => Timestamp::from_str(until).unwrap(),
|
||||||
Ok(event_id) => {
|
None => Timestamp::now(),
|
||||||
let filter = Filter::new().kinds(vec![Kind::TextNote]).event(event_id);
|
};
|
||||||
|
let authors: Vec<PublicKey> = list
|
||||||
|
.into_iter()
|
||||||
|
.map(|hex| PublicKey::from_hex(hex).unwrap())
|
||||||
|
.collect();
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kinds(vec![Kind::TextNote, Kind::Repost])
|
||||||
|
.limit(limit)
|
||||||
|
.until(as_of)
|
||||||
|
.authors(authors);
|
||||||
|
|
||||||
match client.get_events_of(vec![filter], None).await {
|
match client.get_events_of(vec![filter], None).await {
|
||||||
Ok(events) => Ok(events),
|
Ok(events) => Ok(events),
|
||||||
Err(err) => Err(err.to_string()),
|
Err(err) => Err(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Err(_) => Err("Event ID is not valid".into()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -210,9 +228,8 @@ pub async fn repost(raw: &str, state: State<'_, Nostr>) -> Result<EventId, Strin
|
|||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
let event = Event::from_json(raw).unwrap();
|
let event = Event::from_json(raw).unwrap();
|
||||||
|
|
||||||
if let Ok(event_id) = client.repost(&event, None).await {
|
match client.repost(&event, None).await {
|
||||||
Ok(event_id)
|
Ok(event_id) => Ok(event_id),
|
||||||
} else {
|
Err(err) => Err(err.to_string()),
|
||||||
Err("Repost failed".into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user