Merge branch 'main' into new-ui

This commit is contained in:
Alejandro Gomez
2023-01-28 22:43:56 +01:00
57 changed files with 900 additions and 261 deletions

View File

@ -14,7 +14,7 @@ declare global {
nostr: {
getPublicKey: () => Promise<HexKey>,
signEvent: (event: RawEvent) => Promise<RawEvent>,
getRelays: () => Promise<[[string, { read: boolean, write: boolean }]]>,
getRelays: () => Promise<Record<string, { read: boolean, write: boolean }>>,
nip04: {
encrypt: (pubkey: HexKey, content: string) => Promise<string>,
decrypt: (pubkey: HexKey, content: string) => Promise<string>
@ -72,12 +72,22 @@ export default function useEventPublisher() {
return match;
}
const content = msg.replace(/@npub[a-z0-9]+/g, replaceNpub)
.replace(/note[a-z0-9]+/g, replaceNoteId)
.replace(HashtagRegex, replaceHashtag);
.replace(/note[a-z0-9]+/g, replaceNoteId)
.replace(HashtagRegex, replaceHashtag);
ev.Content = content;
}
return {
nip42Auth: async (challenge: string, relay:string) => {
if(pubKey) {
const ev = NEvent.ForPubKey(pubKey);
ev.Kind = EventKind.Auth;
ev.Content = "";
ev.Tags.push(new Tag(["relay", relay], 0));
ev.Tags.push(new Tag(["challenge", challenge], 1));
return await signEvent(ev);
}
},
broadcast: (ev: NEvent | undefined) => {
if (ev) {
console.debug("Sending event: ", ev);
@ -90,8 +100,8 @@ export default function useEventPublisher() {
* When they open the site again we wont see that updated relay list and so it will appear to reset back to the previous state
*/
broadcastForBootstrap: (ev: NEvent | undefined) => {
if(ev) {
for(let [k, _] of DefaultRelays) {
if (ev) {
for (let [k, _] of DefaultRelays) {
System.WriteOnceToRelay(k, ev);
}
}
@ -205,6 +215,9 @@ export default function useEventPublisher() {
temp.add(pkAdd);
}
for (let pk of temp) {
if (pk.length !== 64) {
continue;
}
ev.Tags.push(new Tag(["p", pk], ev.Tags.length));
}
@ -217,7 +230,7 @@ export default function useEventPublisher() {
ev.Kind = EventKind.ContactList;
ev.Content = JSON.stringify(relays);
for (let pk of follows) {
if (pk === pkRemove) {
if (pk === pkRemove || pk.length !== 64) {
continue;
}
ev.Tags.push(new Tag(["p", pk], ev.Tags.length));

View File

@ -7,12 +7,14 @@ import EventKind from "Nostr/EventKind";
import Event from "Nostr/Event";
import { Subscriptions } from "Nostr/Subscriptions";
import { addDirectMessage, setFollows, setRelays, setMuted, setBlocked, sendNotification } from "State/Login";
import type { RootState } from "State/Store";
import { db } from "Db";
import { barierNip07 } from "Feed/EventPublisher";
import { RootState } from "State/Store";
import { mapEventToProfile, MetadataCache } from "State/Users";
import { getDb } from "State/Users/Db";
import useSubscription from "Feed/Subscription";
import { getDisplayName } from "Element/ProfileImage";
import { barierNip07 } from "Feed/EventPublisher";
import { getMutedKeys, getNewest } from "Feed/MuteList";
import { mapEventToProfile, MetadataCache } from "Db/User";
import { MentionRegex } from "Const";
import useModeration from "Hooks/useModeration";
/**
@ -105,9 +107,10 @@ export default function useLoginFeed() {
return acc;
}, { created: 0, profile: null as MetadataCache | null });
if (maxProfile.profile) {
let existing = await db.users.get(maxProfile.profile.pubkey);
const db = getDb()
let existing = await db.find(maxProfile.profile.pubkey);
if ((existing?.created ?? 0) < maxProfile.created) {
await db.users.put(maxProfile.profile);
await db.put(maxProfile.profile);
}
}
})().catch(console.warn);
@ -152,6 +155,7 @@ export default function useLoginFeed() {
}, [dispatch, dmsFeed.store]);
}
async function decryptBlocked(raw: TaggedRawEvent, pubKey: HexKey, privKey?: HexKey) {
const ev = new Event(raw)
if (pubKey && privKey) {

View File

@ -1,27 +1,13 @@
import { useLiveQuery } from "dexie-react-hooks";
import { useEffect } from "react";
import { db } from "Db";
import { MetadataCache } from "Db/User";
import { useEffect, useMemo } from "react";
import { RootState } from "State/Store";
import { MetadataCache } from "State/Users";
import { useKey, useKeys } from "State/Users/Hooks";
import { HexKey } from "Nostr";
import { System } from "Nostr/System";
export default function useProfile(pubKey?: HexKey | Array<HexKey> | undefined): Map<HexKey, MetadataCache> | undefined {
const user = useLiveQuery(async () => {
let userList = new Map<HexKey, MetadataCache>();
if (pubKey) {
if (Array.isArray(pubKey)) {
let ret = await db.users.bulkGet(pubKey);
let filtered = ret.filter(a => a !== undefined).map(a => a!);
return new Map(filtered.map(a => [a.pubkey, a]))
} else {
let ret = await db.users.get(pubKey);
if (ret) {
userList.set(ret.pubkey, ret);
}
}
}
return userList;
}, [pubKey]);
export function useUserProfile(pubKey: HexKey): MetadataCache | undefined {
const users = useKey(pubKey);
useEffect(() => {
if (pubKey) {
@ -30,5 +16,19 @@ export default function useProfile(pubKey?: HexKey | Array<HexKey> | undefined):
}
}, [pubKey]);
return user;
}
return users;
}
export function useUserProfiles(pubKeys: Array<HexKey>): Map<HexKey, MetadataCache> | undefined {
const users = useKeys(pubKeys);
useEffect(() => {
if (pubKeys) {
System.TrackMetadata(pubKeys);
return () => System.UntrackMetadata(pubKeys);
}
}, [pubKeys]);
return users;
}

View File

@ -13,7 +13,7 @@ export interface TimelineFeedOptions {
}
export interface TimelineSubject {
type: "pubkey" | "hashtag" | "global" | "ptag",
type: "pubkey" | "hashtag" | "global" | "ptag" | "keyword",
items: string[]
}
@ -47,6 +47,11 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
sub.PTags = new Set(subject.items);
break;
}
case "keyword": {
sub.Kinds.add(EventKind.SetMetadata);
sub.Search = subject.items[0];
break;
}
}
return sub;
}, [subject.type, subject.items]);
@ -72,6 +77,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
latestSub.Authors = sub.Authors;
latestSub.HashTags = sub.HashTags;
latestSub.Kinds = sub.Kinds;
latestSub.Search = sub.Search;
latestSub.Limit = 1;
latestSub.Since = Math.floor(new Date().getTime() / 1000);
sub.AddSubscription(latestSub);
@ -123,7 +129,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
if (main.store.notes.length > 0) {
setTrackingEvent(s => {
let ids = main.store.notes.map(a => a.id);
if(ids.some(a => !s.includes(a))) {
if (ids.some(a => !s.includes(a))) {
return Array.from(new Set([...s, ...ids]));
}
return s;
@ -165,4 +171,4 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
latest.clear();
}
};
}
}

View File

@ -1,4 +1,5 @@
import * as secp from "@noble/secp256k1";
import { VoidCatHost } from "Const";
/**
* Upload file to void.cat
@ -8,7 +9,7 @@ export default async function VoidUpload(file: File | Blob, filename: string) {
const buf = await file.arrayBuffer();
const digest = await crypto.subtle.digest("SHA-256", buf);
let req = await fetch(`https://void.cat/upload`, {
let req = await fetch(`${VoidCatHost}/upload`, {
mode: "cors",
method: "POST",
body: buf,
@ -17,7 +18,8 @@ export default async function VoidUpload(file: File | Blob, filename: string) {
"V-Content-Type": file.type,
"V-Filename": filename,
"V-Full-Digest": secp.utils.bytesToHex(new Uint8Array(digest)),
"V-Description": "Upload from https://snort.social"
"V-Description": "Upload from https://snort.social",
"V-Strip-Metadata": "true"
}
});