Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,15 @@ function Shopstr({ props }: { props: AppProps }) {
editBlossomContext([], false);
}

const userPubkey = isLoggedIn ? (await signer?.getPubKey()) : undefined;
const initialUserProfileFetch = userPubkey
? fetchProfile(nostr!, allRelays, [userPubkey], editProfileContext).catch(
(error) => {
console.error("Error fetching current user profile:", error);
}
)
: Promise.resolve();

// Fetch products and collect profile pubkeys
let productEvents: NostrEvent[] = [];
let profileSetFromProducts = new Set<string>();
Expand All @@ -553,7 +562,6 @@ function Shopstr({ props }: { props: AppProps }) {

// Handle profile fetching
let pubkeysToFetchProfilesFor = [...profileSetFromProducts];
const userPubkey = (await signer?.getPubKey()) || undefined;
const profileSetFromChats = new Set<string>();

if (isLoggedIn) {
Expand Down Expand Up @@ -590,6 +598,7 @@ function Shopstr({ props }: { props: AppProps }) {
}

try {
await initialUserProfileFetch;
await fetchProfile(
nostr!,
allRelays,
Expand Down
41 changes: 15 additions & 26 deletions pages/settings/user-profile.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState, useContext, useMemo } from "react";
import { useEffect, useState, useContext, useMemo } from "react";
import { SettingsBreadCrumbs } from "@/components/settings/settings-bread-crumbs";
import { ProfileMapContext } from "@/utils/context/context";
import { useForm, Controller } from "react-hook-form";
Expand Down Expand Up @@ -29,7 +29,6 @@ import ShopstrSpinner from "@/components/utility-components/shopstr-spinner";
const UserProfilePage = () => {
const { nostr } = useContext(NostrContext);
const [isUploadingProfile, setIsUploadingProfile] = useState(false);
const [isFetchingProfile, setIsFetchingProfile] = useState(false);
const {
signer,
pubkey: userPubkey,
Expand Down Expand Up @@ -58,36 +57,26 @@ const UserProfilePage = () => {

const watchBanner = watch("banner");
const watchPicture = watch("picture");
const hasCurrentUserProfile =
!!userPubkey && profileContext.profileData.has(userPubkey);
const isFetchingProfile =
!userPubkey || (profileContext.isLoading && !hasCurrentUserProfile);
const defaultImage = useMemo(() => {
return "https://robohash.org/" + userPubkey;
}, [userPubkey]);

const contextLoadedRef = useRef(false);
useEffect(() => {
if (!userPubkey) return;
if (contextLoadedRef.current) return;
setIsFetchingProfile(true);
fetch(`/api/db/fetch-profile?pubkey=${encodeURIComponent(userPubkey)}`)
.then((r) => r.json())
.then((data) => {
if (contextLoadedRef.current) return;
if (data?.profile?.content) reset(data.profile.content);
})
.catch(() => {})
.finally(() => {
if (!contextLoadedRef.current) setIsFetchingProfile(false);
});
}, [userPubkey, reset]);

useEffect(() => {
if (!userPubkey) return;
if (!userPubkey || profileContext.isLoading) return;
const profile = profileContext.profileData.get(userPubkey);
if (!profile) return;
contextLoadedRef.current = true;
setIsFetchingProfile(true);
reset(profile.content);
setIsFetchingProfile(false);
}, [profileContext, userPubkey, reset]);
if (profile) {
reset(profile.content);
}
}, [
userPubkey,
profileContext.isLoading,
profileContext.profileData,
reset,
]);

const onSubmit = async (data: { [x: string]: string }) => {
if (!userPubkey) throw new Error("pubkey is undefined");
Expand Down
46 changes: 30 additions & 16 deletions utils/nostr/nostr-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,20 @@ export class NostrManager {
return signer;
}

private keepAlive(relays: NostrRelay[]) {
for (const relay of relays) {
if (relay.sleeping) {
try {
relay.connect();
relay.sleeping = false;
} catch (e) {
console.error(e);
private async keepAlive(relays: NostrRelay[]) {
await Promise.all(
relays.map(async (relay) => {
if (relay.sleeping) {
try {
await relay.connect();
relay.sleeping = false;
} catch (e) {
console.error(e);
}
}
}
relay.lastActive = Date.now();
}
relay.lastActive = Date.now();
})
);
}

private async gc() {
Expand Down Expand Up @@ -162,7 +164,7 @@ export class NostrManager {
for (const relay of relays) {
relay.activeSubs.push(sub);
}
this.keepAlive(relays);
await this.keepAlive(relays);
return sub;
}

Expand All @@ -187,19 +189,31 @@ export class NostrManager {
const onEvent = params.onevent;
const onEose = params.oneose;
const fetchedEvents: Array<NostrEvent> = [];
let sub: NostrSub | undefined;
let didCloseSub = false;
let didResolve = false;

const closeSubIfNeeded = async () => {
if (!sub || didCloseSub) return;
didCloseSub = true;
await sub.close();
};

params.onevent = (event: NostrEvent) => {
fetchedEvents.push(event);
return onEvent!(event);
};

params.oneose = () => {
sub!.close();
resolve(fetchedEvents);
closeSubIfNeeded().catch(console.error);
if (!didResolve) {
didResolve = true;
resolve(fetchedEvents);
}
return onEose!();
};

const sub = await this.subscribe(filters, params, relayUrls);
sub = await this.subscribe(filters, params, relayUrls);
});
}

Expand All @@ -214,7 +228,7 @@ export class NostrManager {
const relays = relayUrls
? this.relays.filter((r) => relayUrls.includes(r.url))
: this.relays;
this.keepAlive(relays);
await this.keepAlive(relays);
await Promise.allSettled(
this.pool.publish(
relays.map((r) => r.url),
Expand Down