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 { createMutation } from '@tanstack/solid-query';
|
||||||
import ArrowPath from 'heroicons/24/outline/arrow-path.svg';
|
import ArrowPath from 'heroicons/24/outline/arrow-path.svg';
|
||||||
@@ -18,7 +27,7 @@ import useModalState from '@/hooks/useModalState';
|
|||||||
import { useTranslation } from '@/i18n/useTranslation';
|
import { useTranslation } from '@/i18n/useTranslation';
|
||||||
import useCommands from '@/nostr/useCommands';
|
import useCommands from '@/nostr/useCommands';
|
||||||
import useFollowers from '@/nostr/useFollowers';
|
import useFollowers from '@/nostr/useFollowers';
|
||||||
import useFollowings from '@/nostr/useFollowings';
|
import useFollowings, { fetchLatestFollowings } from '@/nostr/useFollowings';
|
||||||
import useProfile from '@/nostr/useProfile';
|
import useProfile from '@/nostr/useProfile';
|
||||||
import usePubkey from '@/nostr/usePubkey';
|
import usePubkey from '@/nostr/usePubkey';
|
||||||
import useSubscription from '@/nostr/useSubscription';
|
import useSubscription from '@/nostr/useSubscription';
|
||||||
@@ -27,6 +36,7 @@ import ensureNonNull from '@/utils/ensureNonNull';
|
|||||||
import epoch from '@/utils/epoch';
|
import epoch from '@/utils/epoch';
|
||||||
import npubEncodeFallback from '@/utils/npubEncodeFallback';
|
import npubEncodeFallback from '@/utils/npubEncodeFallback';
|
||||||
import sleep from '@/utils/sleep';
|
import sleep from '@/utils/sleep';
|
||||||
|
import stripMargin from '@/utils/stripMargin';
|
||||||
import timeout from '@/utils/timeout';
|
import timeout from '@/utils/timeout';
|
||||||
|
|
||||||
export type ProfileDisplayProps = {
|
export type ProfileDisplayProps = {
|
||||||
@@ -130,18 +140,36 @@ const ProfileDisplay: Component<ProfileDisplayProps> = (props) => {
|
|||||||
if (p == null) return;
|
if (p == null) return;
|
||||||
setUpdatingContacts(true);
|
setUpdatingContacts(true);
|
||||||
|
|
||||||
await refetchMyFollowing();
|
|
||||||
await sleep(3000);
|
|
||||||
|
|
||||||
const current = myFollowingPubkeys();
|
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({
|
await updateContactsMutation.mutateAsync({
|
||||||
relayUrls: config().relayUrls,
|
relayUrls: config().relayUrls,
|
||||||
pubkey: p,
|
pubkey: p,
|
||||||
content: myFollowingQuery.data?.content ?? '',
|
content: latest.data()?.content ?? '',
|
||||||
followingPubkeys: uniq(update(current)),
|
followingPubkeys: uniq(update(latest.followingPubkeys())),
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('failed to update contact list', err);
|
||||||
|
window.alert('フォローリストの更新に失敗しました。');
|
||||||
} finally {
|
} finally {
|
||||||
setUpdatingContacts(false);
|
setUpdatingContacts(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,43 @@ export type UseFollowings = {
|
|||||||
query: CreateQueryResult<NostrEvent | null>;
|
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,
|
{ pubkey }: UseFollowingsProps,
|
||||||
signal?: AbortSignal,
|
signal?: AbortSignal,
|
||||||
): Promise<NostrEvent> => {
|
) => {
|
||||||
const task = new BatchedEventsTask({ type: 'Followings', pubkey });
|
const task = new BatchedEventsTask({ type: 'Followings', pubkey });
|
||||||
registerTask({ task, signal });
|
registerTask({ task, signal });
|
||||||
return task.latestEventPromise();
|
|
||||||
|
const latestFollowings = await task.latestEventPromise();
|
||||||
|
return buildMethods(() => latestFollowings);
|
||||||
};
|
};
|
||||||
|
|
||||||
const useFollowings = (propsProvider: () => UseFollowingsProps | null): UseFollowings => {
|
const useFollowings = (propsProvider: () => UseFollowingsProps | null): UseFollowings => {
|
||||||
@@ -51,39 +81,16 @@ const useFollowings = (propsProvider: () => UseFollowingsProps | null): UseFollo
|
|||||||
{
|
{
|
||||||
staleTime: 5 * 60 * 1000, // 5 min
|
staleTime: 5 * 60 * 1000, // 5 min
|
||||||
cacheTime: 24 * 60 * 60 * 1000, // 24 hour
|
cacheTime: 24 * 60 * 60 * 1000, // 24 hour
|
||||||
refetchOnMount: false,
|
refetchOnMount: true,
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
refetchInterval: 0,
|
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());
|
const invalidateFollowings = (): Promise<void> => queryClient.invalidateQueries(genQueryKey());
|
||||||
|
|
||||||
return { followings, followingPubkeys, invalidateFollowings, query };
|
return { ...buildMethods(() => query.data), invalidateFollowings, query };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useFollowings;
|
export default useFollowings;
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ import { createSignal } from 'solid-js';
|
|||||||
|
|
||||||
import { SimplePool } from 'nostr-tools';
|
import { SimplePool } from 'nostr-tools';
|
||||||
|
|
||||||
const [pool] = createSignal<SimplePool>(new SimplePool());
|
const [pool] = createSignal<SimplePool>(new SimplePool({ eoseSubTimeout: 7500 }));
|
||||||
|
|
||||||
const usePool = () => {
|
const usePool = () => pool;
|
||||||
return pool;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default usePool;
|
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