mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-29 00:10:52 +00:00
Fix nip04 messages not having a members field, Improve person search
This commit is contained in:
parent
6c902b7e8f
commit
04b3772231
@ -26,6 +26,8 @@
|
||||
- [x] Fix initial message when opening conversation from a listing
|
||||
- [x] Support frequency value in `price` tag for nip 99
|
||||
- [x] Show all replies exands notes inline rather than opening the note
|
||||
- [x] Fix nip04 messages not having a members field
|
||||
- [x] Improve person search
|
||||
|
||||
# 0.4.0
|
||||
|
||||
|
@ -73,7 +73,8 @@
|
||||
let collapsed = depth === 0
|
||||
let ctx = uniqBy(prop("id"), context)
|
||||
let showEntire = anchor === getIdOrAddress(event)
|
||||
let interactive = !anchor || !showEntire
|
||||
|
||||
const interactive = !anchor || !showEntire
|
||||
|
||||
const onClick = e => {
|
||||
const target = (e.detail?.target || e.target) as HTMLElement
|
||||
|
@ -56,7 +56,7 @@
|
||||
uniq(Tags.from(parent).type("p").values().all().concat(parent.pubkey)),
|
||||
)
|
||||
|
||||
setTimeout(() => compose.write(draft))
|
||||
setTimeout(() => compose.write(draft), 10)
|
||||
}
|
||||
|
||||
const bypassNsecWarning = () => {
|
||||
|
@ -34,6 +34,9 @@ projections.addHandler(30078, async e => {
|
||||
const channel = $channels.get(id)
|
||||
|
||||
$channels.set(id, {
|
||||
relays: [],
|
||||
members: [],
|
||||
messages: [],
|
||||
...channel,
|
||||
last_checked: Math.max(ts, channel?.last_checked || 0),
|
||||
})
|
||||
@ -55,12 +58,7 @@ const handleMessage = async e => {
|
||||
continue
|
||||
}
|
||||
|
||||
const $channel =
|
||||
channels.key(channelId).get() ||
|
||||
({
|
||||
id: channelId,
|
||||
members: pubkeys,
|
||||
} as Channel)
|
||||
const $channel = channels.key(channelId).get()
|
||||
|
||||
const relays = $channel?.relays || []
|
||||
const messages = $channel?.messages || []
|
||||
@ -90,10 +88,12 @@ const handleMessage = async e => {
|
||||
e = {...e, content: await nip04.decryptAsUser(e.content, other)}
|
||||
}
|
||||
|
||||
const updates = {
|
||||
const updates: Channel = {
|
||||
...$channel,
|
||||
id: channelId,
|
||||
relays: uniq([...tags.relays().all(), ...relays]),
|
||||
messages: uniqBy(prop("id"), [e, ...messages]),
|
||||
members: pubkeys,
|
||||
}
|
||||
|
||||
if (e.pubkey === pubkey) {
|
||||
|
@ -165,6 +165,7 @@ export class IndexedDBAdapter {
|
||||
readonly max: number,
|
||||
readonly sort?: (xs: any[]) => any[],
|
||||
readonly filter?: (x: any) => boolean,
|
||||
readonly migrate?: (xs: any[]) => any[],
|
||||
) {}
|
||||
|
||||
getIndexedDBConfig() {
|
||||
@ -177,10 +178,12 @@ export class IndexedDBAdapter {
|
||||
}
|
||||
|
||||
async initialize(storage: Storage) {
|
||||
const {key, store, filter} = this
|
||||
const {key, store} = this
|
||||
const data = await storage.db.getAll(key)
|
||||
const filter = this.filter || identity
|
||||
const migrate = this.migrate || identity
|
||||
|
||||
store.set(data.filter(filter || identity))
|
||||
store.set(migrate(data.filter(filter)))
|
||||
|
||||
store.subscribe(
|
||||
throttle(randomInt(3000, 5000), async <T>(rows: T) => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {prop, sortBy} from "ramda"
|
||||
import {Tags} from 'paravel'
|
||||
import {prop, uniq, sortBy} from "ramda"
|
||||
import {Storage, LocalStorageAdapter, IndexedDBAdapter, sortByPubkeyWhitelist} from "./core"
|
||||
import {_lists} from "./lists"
|
||||
import {people} from "./people"
|
||||
@ -34,6 +35,15 @@ const setAdapter = {
|
||||
load: a => new Set(a || []),
|
||||
}
|
||||
|
||||
// Nip 04 channels weren't getting members set
|
||||
const migrateChannels = channels => {
|
||||
return channels.map(c => {
|
||||
c.members = uniq(c.members.concat(c.messages?.flatMap(m => Tags.from(m).pubkeys().all().concat(m.pubkey))))
|
||||
|
||||
return c
|
||||
})
|
||||
}
|
||||
|
||||
export const storage = new Storage(9, [
|
||||
new LocalStorageAdapter("pubkey", pubkey),
|
||||
new LocalStorageAdapter("sessions", sessions),
|
||||
@ -51,7 +61,7 @@ export const storage = new Storage(9, [
|
||||
),
|
||||
new IndexedDBAdapter("people", people, 5000, sortByPubkeyWhitelist(prop("last_fetched"))),
|
||||
new IndexedDBAdapter("relays", relays, 1000, sortBy(prop("count"))),
|
||||
new IndexedDBAdapter("channels", channels, 1000, sortBy(prop("last_checked"))),
|
||||
new IndexedDBAdapter("channels", channels, 1000, sortBy(prop("last_checked")), null, migrateChannels),
|
||||
new IndexedDBAdapter("groups", groups, 1000, sortBy(prop("count"))),
|
||||
new IndexedDBAdapter("groupAlerts", groupAlerts, 30, sortBy(prop("created_at"))),
|
||||
new IndexedDBAdapter("groupRequests", groupRequests, 100, sortBy(prop("created_at"))),
|
||||
|
@ -1,12 +1,15 @@
|
||||
import {defaultTo, filter} from "ramda"
|
||||
import Fuse from "fuse.js"
|
||||
import {doPipe} from "hurdak"
|
||||
import {defaultTo, map, filter, sortBy} from "ramda"
|
||||
import {derived} from "src/engine/core/utils"
|
||||
import {pubkey} from "src/engine/session/state"
|
||||
import {user} from "src/engine/session/derived"
|
||||
import type {Person} from "./model"
|
||||
import {people} from "./state"
|
||||
import {personHasName, getPeopleSearch, getMutes, getFollows, getNetwork} from "./utils"
|
||||
import {personHasName, getFollowsWhoFollow, primeWotCaches, getWotScore, getMutes, getFollows, getNetwork} from "./utils"
|
||||
|
||||
export const peopleWithName = people.derived(filter(personHasName))
|
||||
|
||||
export const searchPeople = peopleWithName.derived(getPeopleSearch)
|
||||
|
||||
export const derivePerson = pubkey => people.key(pubkey).derived(defaultTo({pubkey}))
|
||||
|
||||
export const mutes = user.derived(getMutes)
|
||||
@ -18,3 +21,35 @@ export const network = user.derived(getNetwork)
|
||||
export const deriveMuted = (value: string) => mutes.derived(s => s.has(value))
|
||||
|
||||
export const deriveFollowing = (pubkey: string) => follows.derived(s => s.has(pubkey))
|
||||
|
||||
export const searchPeople = derived(
|
||||
[pubkey, peopleWithName.throttle(300)],
|
||||
([$pubkey, $peopleWithName]: [string, Person[]]): ((term: string) => Person[]) => {
|
||||
primeWotCaches($pubkey)
|
||||
|
||||
const options = $peopleWithName.map(p => ({person: p, score: getWotScore($pubkey, p.pubkey)}))
|
||||
|
||||
const fuse = new Fuse(options, {
|
||||
keys: [
|
||||
"person.profile.name",
|
||||
"person.profile.display_name",
|
||||
{name: "person.profile.nip05", weight: 0.5},
|
||||
{name: "person.profile.about", weight: 0.1},
|
||||
],
|
||||
threshold: 0.3,
|
||||
shouldSort: false,
|
||||
includeScore: true,
|
||||
})
|
||||
|
||||
return (term: string) => {
|
||||
if (!term) {
|
||||
return sortBy(item => -item.score, options).map(item => item.person)
|
||||
}
|
||||
|
||||
return doPipe(fuse.search(term), [
|
||||
sortBy((r: any) => (r.score - 1) * Math.sqrt(Math.max(0, r.item.score))),
|
||||
map((r: any) => r.item.person),
|
||||
])
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1,8 +1,9 @@
|
||||
import {nip19} from "nostr-tools"
|
||||
import {throttle} from "throttle-debounce"
|
||||
import {fromNostrURI, cached} from "paravel"
|
||||
import {uniq, join, nth, last} from "ramda"
|
||||
import {Fetch, tryFunc, createMapOf, ellipsize, switcherFn} from "hurdak"
|
||||
import {fuzzy, createBatcher, pushToKey} from "src/util/misc"
|
||||
import {createBatcher, pushToKey} from "src/util/misc"
|
||||
import {dufflepud} from "src/engine/session/utils"
|
||||
import {getPubkeyHints} from "src/engine/relays/utils"
|
||||
import type {Person, Handle} from "./model"
|
||||
@ -58,17 +59,6 @@ export const displayHandle = (handle: Handle) =>
|
||||
|
||||
export const displayPubkey = (pubkey: string) => displayPerson(getPersonWithDefault(pubkey))
|
||||
|
||||
export const getPeopleSearch = $people =>
|
||||
fuzzy($people, {
|
||||
keys: [
|
||||
"profile.name",
|
||||
"profile.display_name",
|
||||
{name: "profile.nip05", weight: 0.5},
|
||||
{name: "about", weight: 0.1},
|
||||
],
|
||||
threshold: 0.3,
|
||||
})
|
||||
|
||||
export const getMutedPubkeys = $person => ($person?.mutes || []).map(nth(1)) as string[]
|
||||
|
||||
export const getMutes = $person => new Set(getMutedPubkeys($person))
|
||||
@ -116,7 +106,7 @@ export const getFollowsWhoMute = cached({
|
||||
getFollowedPubkeys(people.key(pk).get()).filter(pk => isMuting(people.key(pk).get(), tpk)),
|
||||
})
|
||||
|
||||
export const primeWotCaches = pk => {
|
||||
export const primeWotCaches = throttle(3000, pk => {
|
||||
const mutes = {}
|
||||
const follows = {}
|
||||
|
||||
@ -153,7 +143,7 @@ export const primeWotCaches = pk => {
|
||||
getFollowsWhoFollow.cache.set(getFollowsWhoFollow.getKey([pk, person.pubkey]), [])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const getWotScore = (pk, tpk) => {
|
||||
if (!people.key(pk).exists()) {
|
||||
|
@ -19,11 +19,15 @@
|
||||
let input, suggestions, popover
|
||||
let focused = Boolean(autofocus)
|
||||
|
||||
$: suggestions?.setData(term ? search(term).slice(0, 10) : defaultOptions)
|
||||
$: {
|
||||
suggestions?.setData(term ? search(term).slice(0, 10) : defaultOptions)
|
||||
}
|
||||
|
||||
$: {
|
||||
if (!focused || !term) {
|
||||
popover?.hide()
|
||||
} else {
|
||||
popover?.show()
|
||||
}
|
||||
|
||||
if (popover) {
|
||||
|
Loading…
Reference in New Issue
Block a user