fix: lost contacts

This commit is contained in:
Shusui MOYATANI
2023-06-18 01:10:25 +09:00
parent 6ba622328b
commit c97dcc94e3
3 changed files with 46 additions and 51 deletions

View File

@@ -24,6 +24,7 @@ import useVerification from '@/nostr/useVerification';
import ensureNonNull from '@/utils/ensureNonNull';
import epoch from '@/utils/epoch';
import npubEncodeFallback from '@/utils/npubEncodeFallback';
import sleep from '@/utils/sleep';
import timeout from '@/utils/timeout';
export type ProfileDisplayProps = {
@@ -47,6 +48,7 @@ const ProfileDisplay: Component<ProfileDisplayProps> = (props) => {
const npub = createMemo(() => npubEncodeFallback(props.pubkey));
const [updatingContacts, setUpdatingContacts] = createSignal(false);
const [hoverFollowButton, setHoverFollowButton] = createSignal(false);
const [showFollowers, setShowFollowers] = createSignal(false);
@@ -117,48 +119,42 @@ const ProfileDisplay: Component<ProfileDisplayProps> = (props) => {
},
});
const handlePromise =
<Params extends any[], T>(f: (...params: Params) => Promise<T>) =>
(onError: (err: any) => void) =>
(...params: Params) => {
f(...params).catch((err) => {
onError(err);
const updateContacts = async (update: (current: string[]) => string[]) => {
try {
const p = myPubkey();
if (p == null) return;
setUpdatingContacts(true);
await refetchMyFollowing();
await sleep(3000);
const current = myFollowingPubkeys();
console.debug('current pubkeys', current);
await updateContactsMutation.mutateAsync({
relayUrls: config().relayUrls,
pubkey: p,
content: myFollowingQuery.data?.content ?? '',
followingPubkeys: uniq(update(current)),
});
} finally {
setUpdatingContacts(false);
}
};
const follow = () => {
updateContacts((current) => [...current, props.pubkey]).catch((err) => {
console.log('failed to follow', err);
});
};
const follow = handlePromise(async () => {
const p = myPubkey();
if (p == null) return;
if (!myFollowingQuery.isFetched) return;
await refetchMyFollowing();
updateContactsMutation.mutate({
relayUrls: config().relayUrls,
pubkey: p,
content: myFollowingQuery.data?.content ?? '',
followingPubkeys: uniq([...myFollowingPubkeys(), props.pubkey]),
});
})((err) => {
console.log('failed to follow', err);
});
const unfollow = handlePromise(async () => {
const p = myPubkey();
if (p == null) return;
if (!myFollowingQuery.isFetched) return;
const unfollow = () => {
if (!window.confirm('本当にフォロー解除しますか?')) return;
await refetchMyFollowing();
updateContactsMutation.mutate({
relayUrls: config().relayUrls,
pubkey: p,
content: myFollowingQuery.data?.content ?? '',
followingPubkeys: myFollowingPubkeys().filter((k) => k !== props.pubkey),
});
})((err) => {
updateContacts((current) => current.filter((k) => k !== props.pubkey)).catch((err) => {
console.log('failed to unfollow', err);
});
};
const menu: MenuItem[] = [
/*
@@ -247,16 +243,16 @@ const ProfileDisplay: Component<ProfileDisplayProps> = (props) => {
</button>
</Match>
<Match when={updateContactsMutation.isLoading || updatingContacts()}>
<span class="rounded-full border border-primary px-4 py-2 text-primary sm:text-base">
</span>
</Match>
<Match when={myFollowingQuery.isLoading || myFollowingQuery.isFetching}>
<span class="rounded-full border border-primary px-4 py-2 text-primary sm:text-base">
</span>
</Match>
<Match when={updateContactsMutation.isLoading}>
<span class="rounded-full border border-primary px-4 py-2 text-primary sm:text-base">
</span>
</Match>
<Match when={following()}>
<button
class="rounded-full border border-primary bg-primary px-4 py-2

View File

@@ -56,7 +56,7 @@ const useFollowings = (propsProvider: () => UseFollowingsProps | null): UseFollo
{
staleTime: 5 * 60 * 1000, // 5 min
cacheTime: 24 * 60 * 60 * 1000, // 24 hour
refetchOnMount: false,
refetchOnMount: true,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchInterval: 0,

View File

@@ -33,14 +33,6 @@ export type UseProfiles = {
type UseProfileQueryKey = readonly ['useProfile', UseProfileProps | null];
const queryOptions = {
// Profiles are updated occasionally, so a short staleTime is used here.
// cacheTime is long so that the user see profiles instantly.
staleTime: 5 * 60 * 1000, // 5 min
cacheTime: 24 * 60 * 60 * 1000, // 1 day
refetchInterval: 5 * 60 * 1000, // 5 min
};
const getProfile = ({
queryKey,
signal,
@@ -71,7 +63,7 @@ const getProfile = ({
return latestEvent();
});
// TODO timeoutと同時にsignalでキャンセルするようにしたい
return timeout(15000, `useProfile: ${pubkey}`)(promise);
return timeout(3000, `useProfile: ${pubkey}`)(promise);
};
const useProfile = (propsProvider: () => UseProfileProps | null): UseProfile => {
@@ -82,7 +74,14 @@ const useProfile = (propsProvider: () => UseProfileProps | null): UseProfile =>
const query = createQuery(
genQueryKey,
({ queryKey, signal }) => getProfile({ queryKey, signal, queryClient }),
queryOptions,
{
// Profiles are updated occasionally, so a short staleTime is used here.
// cacheTime is long so that the user see profiles instantly.
staleTime: 5 * 60 * 1000, // 5 min
cacheTime: 24 * 60 * 60 * 1000, // 1 day
refetchInterval: 5 * 60 * 1000, // 5 min
refetchOnWindowFocus: false,
},
);
const profile = createMemo((): Profile | null => {