respect user's relay list (kind 10002)

This commit is contained in:
Ren Amamiya 2023-09-19 08:01:57 +07:00
parent 380d1fb930
commit 60e93965ea
7 changed files with 30 additions and 26 deletions

View File

@ -0,0 +1,2 @@
-- Add migration script here
CREATE UNIQUE INDEX unique_relay ON relays (relay);

View File

@ -211,6 +211,12 @@ fn main() {
sql: include_str!("../migrations/20230817014932_add_last_login_time_to_account.sql"), sql: include_str!("../migrations/20230817014932_add_last_login_time_to_account.sql"),
kind: MigrationKind::Up, kind: MigrationKind::Up,
}, },
Migration {
version: 20230918235335,
description: "add unique to relay",
sql: include_str!("../migrations/20230918235335_add_uniq_to_relay.sql"),
kind: MigrationKind::Up,
},
], ],
) )
.build(), .build(),

View File

@ -93,7 +93,7 @@ export function ImportStep2Screen() {
<p className="text-white/70"> <p className="text-white/70">
Password is not related to your Nostr account. It is only used to secure your Password is not related to your Nostr account. It is only used to secure your
keys stored on your local machine and to unlock the app (like unlocking your keys stored on your local machine and to unlock the app (like unlocking your
phone with a passcode). When you move to other Nostr clients, you just need to phone with a passcode). When you move to other Nostr clients, you only need to
copy your private key. copy your private key.
</p> </p>
</div> </div>

View File

@ -82,8 +82,8 @@ export function ImportStep3Screen() {
)} )}
</button> </button>
<span className="text-center text-sm text-white/50"> <span className="text-center text-sm text-white/50">
By clicking &apos;Continue&apos;, Lume will download your relay list and all By clicking &apos;Continue&apos;, Lume will download your old relay list and
events from the last 24 hours. It may take a bit all events from the last 24 hours. It may take a bit
</span> </span>
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
// inspire by: https://github.com/nostr-dev-kit/ndk-react/ // inspire by: https://github.com/nostr-dev-kit/ndk-react/
import NDK from '@nostr-dev-kit/ndk'; import NDK from '@nostr-dev-kit/ndk';
import { message } from '@tauri-apps/api/dialog'; import { message } from '@tauri-apps/api/dialog';
import { fetch } from '@tauri-apps/api/http';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import TauriAdapter from '@libs/ndk/cache'; import TauriAdapter from '@libs/ndk/cache';
@ -16,39 +17,36 @@ export const NDKInstance = () => {
// TODO: fully support NIP-11 // TODO: fully support NIP-11
async function getExplicitRelays() { async function getExplicitRelays() {
try { try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort('timeout'), 10000);
// get relays // get relays
const relays = await db.getExplicitRelayUrls(); const relays = await db.getExplicitRelayUrls();
const requests = relays.map((relay) => { const requests = relays.map((relay) => {
const url = new URL(relay); const url = new URL(relay);
return fetch(`https://${url.hostname + url.pathname}`, { return fetch(`https://${url.hostname + url.pathname}`, {
headers: { Accept: 'application/nostr+json' }, method: 'GET',
signal: controller.signal, timeout: 10,
headers: {
Accept: 'application/nostr+json',
},
}); });
}); });
const responses = await Promise.all(requests); const responses = await Promise.all(requests);
const successes = responses.filter((res) => res.ok); const successes = responses.filter((res) => res.ok);
const errors = responses.filter((res) => !res.ok);
if (errors.length > 0) throw errors.map((response) => Error(response.statusText));
const verifiedRelays: string[] = successes.map((res) => { const verifiedRelays: string[] = successes.map((res) => {
const url = new URL(res.url); // TODO: support payment
if (url.protocol === 'http:') return `ws://${url.hostname + url.pathname}`; // @ts-expect-error, not have type yet
if (url.protocol === 'https:') return `wss://${url.hostname + url.pathname}`; if (!res.data.limitation?.payment_required) {
const url = new URL(res.url);
if (url.protocol === 'http:') return `ws://${url.hostname + url.pathname}`;
if (url.protocol === 'https:') return `wss://${url.hostname + url.pathname}`;
}
}); });
// clear timeout // return all validated relays
clearTimeout(timeoutId);
// return all validate relays
return verifiedRelays; return verifiedRelays;
} catch (e) { } catch (e) {
await message(e, { title: 'Cannot connect to relays', type: 'error' }); console.error(e);
} }
} }

View File

@ -283,15 +283,14 @@ export class LumeStorage {
} }
public async getExplicitRelayUrls() { public async getExplicitRelayUrls() {
if (!this.account) return null; if (!this.account) return FULL_RELAYS;
const result: Relays[] = await this.db.select( const result: Relays[] = await this.db.select(
`SELECT * FROM relays WHERE account_id = "${this.account.id}" ORDER BY id DESC LIMIT 50;` `SELECT * FROM relays WHERE account_id = "${this.account.id}" ORDER BY id DESC LIMIT 50;`
); );
if (result.length < 1) return FULL_RELAYS; if (!result || result.length < 1) return FULL_RELAYS;
// return [...new Set(result.map((el) => el.relay))]; return result.map((el) => el.relay);
return FULL_RELAYS;
} }
public async createRelay(relay: string, purpose?: string) { public async createRelay(relay: string, purpose?: string) {

View File

@ -57,7 +57,7 @@ export function useNostr() {
const follows = new Set<string>(preFollows || []); const follows = new Set<string>(preFollows || []);
const lruNetwork = new LRUCache<string, string, void>({ max: 300 }); const lruNetwork = new LRUCache<string, string, void>({ max: 300 });
/* fetch user's relays // fetch user's relays
const relayEvents = await ndk.fetchEvents({ const relayEvents = await ndk.fetchEvents({
kinds: [NDKKind.RelayList], kinds: [NDKKind.RelayList],
authors: [db.account.pubkey], authors: [db.account.pubkey],
@ -74,7 +74,6 @@ export function useNostr() {
} }
} }
} }
*/
// fetch user's follows // fetch user's follows
if (!preFollows) { if (!preFollows) {