mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-18 22:44:26 +01:00
fix: fetch latest contact list
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
import { Component, createSignal, createMemo, Show, Switch, Match, createEffect } from 'solid-js';
|
||||
import {
|
||||
Component,
|
||||
createSignal,
|
||||
createMemo,
|
||||
Show,
|
||||
Switch,
|
||||
Match,
|
||||
createEffect,
|
||||
onMount,
|
||||
} from 'solid-js';
|
||||
|
||||
import { createMutation } from '@tanstack/solid-query';
|
||||
import ArrowPath from 'heroicons/24/outline/arrow-path.svg';
|
||||
@@ -18,7 +27,7 @@ import useModalState from '@/hooks/useModalState';
|
||||
import { useTranslation } from '@/i18n/useTranslation';
|
||||
import useCommands from '@/nostr/useCommands';
|
||||
import useFollowers from '@/nostr/useFollowers';
|
||||
import useFollowings from '@/nostr/useFollowings';
|
||||
import useFollowings, { fetchLatestFollowings } from '@/nostr/useFollowings';
|
||||
import useProfile from '@/nostr/useProfile';
|
||||
import usePubkey from '@/nostr/usePubkey';
|
||||
import useSubscription from '@/nostr/useSubscription';
|
||||
@@ -27,6 +36,7 @@ import ensureNonNull from '@/utils/ensureNonNull';
|
||||
import epoch from '@/utils/epoch';
|
||||
import npubEncodeFallback from '@/utils/npubEncodeFallback';
|
||||
import sleep from '@/utils/sleep';
|
||||
import stripMargin from '@/utils/stripMargin';
|
||||
import timeout from '@/utils/timeout';
|
||||
|
||||
export type ProfileDisplayProps = {
|
||||
@@ -130,18 +140,36 @@ const ProfileDisplay: Component<ProfileDisplayProps> = (props) => {
|
||||
if (p == null) return;
|
||||
setUpdatingContacts(true);
|
||||
|
||||
await refetchMyFollowing();
|
||||
await sleep(3000);
|
||||
|
||||
const current = myFollowingPubkeys();
|
||||
console.debug('current pubkeys', current);
|
||||
const latest = await fetchLatestFollowings({ pubkey: p });
|
||||
|
||||
const msg = stripMargin`
|
||||
フォローリストが空のようです。初めてのフォローであれば問題ありません。
|
||||
そうでなければ、リレーとの接続がうまくいっていない可能性があります。ページを再読み込みしてリレーと再接続してください。
|
||||
また、他のクライアントと同じリレーを設定できているどうかご確認ください。
|
||||
|
||||
続行しますか?
|
||||
`;
|
||||
|
||||
if ((latest.data() == null || latest.followingPubkeys().length === 0) && !window.confirm(msg))
|
||||
return;
|
||||
|
||||
if ((latest?.data()?.created_at ?? 0) < (myFollowingQuery.data?.created_at ?? 0)) {
|
||||
window.alert(
|
||||
'最新のフォローリストを取得できませんでした。リレーの接続状況が悪い可能性があります。',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await updateContactsMutation.mutateAsync({
|
||||
relayUrls: config().relayUrls,
|
||||
pubkey: p,
|
||||
content: myFollowingQuery.data?.content ?? '',
|
||||
followingPubkeys: uniq(update(current)),
|
||||
content: latest.data()?.content ?? '',
|
||||
followingPubkeys: uniq(update(latest.followingPubkeys())),
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('failed to update contact list', err);
|
||||
window.alert('フォローリストの更新に失敗しました。');
|
||||
} finally {
|
||||
setUpdatingContacts(false);
|
||||
}
|
||||
|
||||
@@ -24,13 +24,43 @@ export type UseFollowings = {
|
||||
query: CreateQueryResult<NostrEvent | null>;
|
||||
};
|
||||
|
||||
export const fetchLatestFollowings = (
|
||||
const buildMethods = (dataProvider: () => NostrEvent | undefined | null) => {
|
||||
const followings = () => {
|
||||
const data = dataProvider();
|
||||
if (data == null) return [];
|
||||
|
||||
const result: Following[] = [];
|
||||
|
||||
// TODO zodにする
|
||||
const event = genericEvent(data);
|
||||
event.pTags().forEach((tag) => {
|
||||
const [, followingPubkey, mainRelayUrl, petname] = tag;
|
||||
|
||||
const following: Following = { pubkey: followingPubkey, petname };
|
||||
if (mainRelayUrl != null && mainRelayUrl.length > 0) {
|
||||
following.mainRelayUrl = mainRelayUrl;
|
||||
}
|
||||
|
||||
result.push(following);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const followingPubkeys = (): string[] => followings().map((follow) => follow.pubkey);
|
||||
|
||||
return { followings, followingPubkeys, data: dataProvider };
|
||||
};
|
||||
|
||||
export const fetchLatestFollowings = async (
|
||||
{ pubkey }: UseFollowingsProps,
|
||||
signal?: AbortSignal,
|
||||
): Promise<NostrEvent> => {
|
||||
) => {
|
||||
const task = new BatchedEventsTask({ type: 'Followings', pubkey });
|
||||
registerTask({ task, signal });
|
||||
return task.latestEventPromise();
|
||||
|
||||
const latestFollowings = await task.latestEventPromise();
|
||||
return buildMethods(() => latestFollowings);
|
||||
};
|
||||
|
||||
const useFollowings = (propsProvider: () => UseFollowingsProps | null): UseFollowings => {
|
||||
@@ -51,39 +81,16 @@ 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,
|
||||
},
|
||||
);
|
||||
|
||||
const followings = () => {
|
||||
if (query.data == null) return [];
|
||||
|
||||
const result: Following[] = [];
|
||||
|
||||
// TODO zodにする
|
||||
const event = genericEvent(query.data);
|
||||
event.pTags().forEach((tag) => {
|
||||
const [, followingPubkey, mainRelayUrl, petname] = tag;
|
||||
|
||||
const following: Following = { pubkey: followingPubkey, petname };
|
||||
if (mainRelayUrl != null && mainRelayUrl.length > 0) {
|
||||
following.mainRelayUrl = mainRelayUrl;
|
||||
}
|
||||
|
||||
result.push(following);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const followingPubkeys = (): string[] => followings().map((follow) => follow.pubkey);
|
||||
|
||||
const invalidateFollowings = (): Promise<void> => queryClient.invalidateQueries(genQueryKey());
|
||||
|
||||
return { followings, followingPubkeys, invalidateFollowings, query };
|
||||
return { ...buildMethods(() => query.data), invalidateFollowings, query };
|
||||
};
|
||||
|
||||
export default useFollowings;
|
||||
|
||||
@@ -2,10 +2,8 @@ import { createSignal } from 'solid-js';
|
||||
|
||||
import { SimplePool } from 'nostr-tools';
|
||||
|
||||
const [pool] = createSignal<SimplePool>(new SimplePool());
|
||||
const [pool] = createSignal<SimplePool>(new SimplePool({ eoseSubTimeout: 7500 }));
|
||||
|
||||
const usePool = () => {
|
||||
return pool;
|
||||
};
|
||||
const usePool = () => pool;
|
||||
|
||||
export default usePool;
|
||||
|
||||
24
src/utils/stripMargin.ts
Normal file
24
src/utils/stripMargin.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
const stripMargin = (strings: TemplateStringsArray, ...values: any[]) => {
|
||||
const s = String.raw(strings, values);
|
||||
|
||||
const result = [];
|
||||
const lines = s.split('\n');
|
||||
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
const line = lines[i];
|
||||
const marginRemoved = line.trimStart();
|
||||
if (result.length > 0 || marginRemoved.length > 0) {
|
||||
result.push(marginRemoved);
|
||||
}
|
||||
}
|
||||
|
||||
while (result.length > 0) {
|
||||
const lastLine = result[result.length - 1];
|
||||
if (lastLine.length > 0) break;
|
||||
result.pop();
|
||||
}
|
||||
|
||||
return result.join('\n');
|
||||
};
|
||||
|
||||
export default stripMargin;
|
||||
Reference in New Issue
Block a user