support nip94 and fix some bugs

This commit is contained in:
Ren Amamiya
2023-08-09 09:04:16 +07:00
parent e6c6793f6e
commit d1d0a462f4
11 changed files with 285 additions and 166 deletions

View File

@@ -9,6 +9,7 @@ import { updateAccount } from '@libs/storage';
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
import { useAccount } from '@utils/hooks/useAccount';
import { useNostr } from '@utils/hooks/useNostr';
import { usePublish } from '@utils/hooks/usePublish';
import { arrayToNIP02 } from '@utils/transform';
@@ -17,6 +18,7 @@ export function OnboardStep1Screen() {
const navigate = useNavigate();
const { publish } = usePublish();
const { fetchNotes } = useNostr();
const { account } = useAccount();
const { status, data } = useQuery(['trending-profiles'], async () => {
const res = await fetch('https://api.nostr.band/v0/trending/profiles');
@@ -45,8 +47,10 @@ export function OnboardStep1Screen() {
const event = await publish({ content: '', kind: 3, tags: tags });
await updateAccount('follows', follows);
const notes = await fetchNotes();
// redirect to next step
if (event) {
if (event && notes) {
setTimeout(() => {
queryClient.invalidateQueries(['currentAccount']);
navigate('/auth/onboarding/step-2', { replace: true });

View File

@@ -109,6 +109,13 @@ export function OnboardStep3Screen() {
<div className="flex h-full w-full items-center justify-center">
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
</div>
) : relaysAsArray.length === 0 ? (
<div className="flex h-full w-full items-center justify-center">
<p className="text-center text-white/50">
Can&apos;t found any relays, you can skip this step and use default relays
instead
</p>
</div>
) : (
relaysAsArray.map((item, index) => (
<button
@@ -118,7 +125,7 @@ export function OnboardStep3Screen() {
className="inline-flex transform items-start justify-between bg-white/10 px-4 py-2 hover:bg-white/20"
>
<div className="flex flex-col items-start gap-1">
{item.replace(/\/+$/, '')}
<p className="max-w-[15rem] truncate">{item.replace(/\/+$/, '')}</p>
<UserRelay pubkey={data.get(item)} />
</div>
{relays.has(item) && (

View File

@@ -1,4 +1,4 @@
import { FetchOptions, ResponseType, fetch } from '@tauri-apps/plugin-http';
import { fetch } from '@tauri-apps/plugin-http';
import * as cheerio from 'cheerio';
import { OPENGRAPH } from '@stores/constants';
@@ -332,10 +332,9 @@ function parseResponse(response: IPreFetchedResource, options?: ILinkPreviewOpti
export async function getLinkPreview(text: string) {
const fetchUrl = text;
const options: FetchOptions = {
const options = {
method: 'GET',
timeout: 5,
responseType: ResponseType.Text,
};
let response = await fetch(fetchUrl, options);

View File

@@ -529,10 +529,15 @@ export async function getRelays() {
export async function getExplicitRelayUrls() {
const db = await connect();
const activeAccount = await getActiveAccount();
if (!activeAccount) return null;
const result: Relays[] = await db.select(
`SELECT * FROM relays WHERE account_id = "${activeAccount.id}";`
);
if (result.length > 0) return result.map((el) => el.relay);
return null;
}
@@ -541,7 +546,7 @@ export async function createRelay(relay: string, purpose?: string) {
const db = await connect();
const activeAccount = await getActiveAccount();
return await db.execute(
'INSERT OR IGNORE INTO blocks (account_id, relay, purpose) VALUES (?, ?, ?);',
'INSERT OR IGNORE INTO relays (account_id, relay, purpose) VALUES (?, ?, ?);',
[activeAccount.id, relay, purpose || '']
);
}

View File

@@ -60,7 +60,7 @@ export function Composer() {
});
const uploadImage = async (file?: string) => {
const image = await upload(file);
const image = await upload(file, true);
if (image.url) {
editor.commands.setImage({ src: image.url });
editor.commands.createParagraphNear();

View File

@@ -66,6 +66,7 @@ export const OPENGRAPH = {
export const FULL_RELAYS = [
'wss://relayable.org',
'wss://relay.damus.io',
'wss://relay.nostr.band/all',
'wss://nostr.mutinywallet.com',
];

View File

@@ -1,6 +1,6 @@
import { readBinaryFile } from '@tauri-apps/plugin-fs';
export async function createBlobFromFile(path: string): Promise<Uint8Array> {
export async function createBlobFromFile(path: string): Promise<Blob> {
const file = await readBinaryFile(path);
return file;
return new Blob([file]);
}

View File

@@ -1,28 +1,17 @@
import { magnetDecode } from '@ctrl/magnet-link';
import { open } from '@tauri-apps/plugin-dialog';
import { Body, fetch } from '@tauri-apps/plugin-http';
import { VoidApi } from '@void-cat/api';
import { createBlobFromFile } from '@utils/createBlobFromFile';
interface UploadResponse {
fileID?: string;
fileName?: string;
imageUrl?: string;
lightningDestination?: string;
lightningPaymentLink?: string;
message?: string;
route?: string;
status: number;
success: boolean;
url?: string;
data?: {
url?: string;
};
}
import { usePublish } from '@utils/hooks/usePublish';
export function useImageUploader() {
const upload = async (file: null | string, nip94?: boolean) => {
let filepath = file;
const { publish } = usePublish();
const upload = async (file: null | string, nip94?: boolean) => {
const voidcat = new VoidApi('https://void.cat');
let filepath = file;
if (!file) {
const selected = await open({
multiple: false,
@@ -38,39 +27,46 @@ export function useImageUploader() {
} else if (selected === null) {
// user cancelled the selection
} else {
filepath = selected;
filepath = selected.path;
}
}
const filename = filepath.split('/').pop();
const filetype = 'image/' + filename.split('.').pop();
const filetype = filename.split('.').pop();
const blob = await createBlobFromFile(filepath);
const res = await fetch('https://nostrimg.com/api/upload', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: Body.form({
keys: filename,
image: {
file: blob,
mime: filetype,
fileName: filename,
},
}),
});
const uploader = voidcat.getUploader(blob);
// upload file
const res = await uploader.upload();
if (res.ok) {
const data = res.data as UploadResponse;
if (typeof data?.imageUrl === 'string' && data.success) {
if (nip94) {
console.log('todo');
const url =
res.file?.metadata?.url ?? `https://void.cat/d/${res.file?.id}.${filetype}`;
console.log(url);
if (nip94) {
const tags = [
['url', url],
['x', res.file?.metadata?.digest ?? ''],
['m', res.file?.metadata?.mimeType ?? 'application/octet-stream'],
['size', res.file?.metadata?.size.toString() ?? '0'],
];
if (res.file?.metadata?.magnetLink) {
tags.push(['magnet', res.file.metadata.magnetLink]);
const parsedMagnet = magnetDecode(res.file.metadata.magnetLink);
if (parsedMagnet?.infoHash) {
tags.push(['i', parsedMagnet?.infoHash]);
}
}
return {
url: new URL(data.imageUrl).toString(),
};
await publish({ content: '', kind: 1063, tags: tags });
}
return {
url: url,
};
}
return {