Fix inbox relays, add time functions
This commit is contained in:
@@ -16,6 +16,7 @@ export * from './sync'
|
|||||||
export * from './tags'
|
export * from './tags'
|
||||||
export * from './thunk'
|
export * from './thunk'
|
||||||
export * from './topics'
|
export * from './topics'
|
||||||
|
export * from './user'
|
||||||
export * from './util'
|
export * from './util'
|
||||||
export * from './wot'
|
export * from './wot'
|
||||||
export * from './zappers'
|
export * from './zappers'
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {repository, load} from './core'
|
|||||||
import {createSearch} from './util'
|
import {createSearch} from './util'
|
||||||
import {collection} from './collection'
|
import {collection} from './collection'
|
||||||
import {loadRelaySelections} from './relaySelections'
|
import {loadRelaySelections} from './relaySelections'
|
||||||
import {getUserWotScore} from './wot'
|
import {wotGraph} from './wot'
|
||||||
|
|
||||||
export const profiles = withGetter(
|
export const profiles = withGetter(
|
||||||
deriveEventsMapped<PublishedProfile>(repository, {
|
deriveEventsMapped<PublishedProfile>(repository, {
|
||||||
@@ -58,8 +58,13 @@ export const profileSearch = derived(profiles, $profiles =>
|
|||||||
createSearch($profiles, {
|
createSearch($profiles, {
|
||||||
onSearch: searchProfiles,
|
onSearch: searchProfiles,
|
||||||
getValue: (profile: PublishedProfile) => profile.event.pubkey,
|
getValue: (profile: PublishedProfile) => profile.event.pubkey,
|
||||||
sortFn: ({score, item}) =>
|
sortFn: ({score, item}) => {
|
||||||
score! < 0.1 ? dec(score!) * getUserWotScore(item.event.pubkey) : -score!,
|
if (score && score > 0.1) return -score!
|
||||||
|
|
||||||
|
const wotScore = wotGraph.get().get(item.event.pubkey) || 0
|
||||||
|
|
||||||
|
return score ? dec(score) * wotScore : -wotScore
|
||||||
|
},
|
||||||
fuseOptions: {
|
fuseOptions: {
|
||||||
keys: ["name", "display_name", {name: "about", weight: 0.3}],
|
keys: ["name", "display_name", {name: "about", weight: 0.3}],
|
||||||
threshold: 0.3,
|
threshold: 0.3,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const {
|
|||||||
load({...request, filters: [{kinds: [RELAYS], authors: [pubkey]}]}),
|
load({...request, filters: [{kinds: [RELAYS], authors: [pubkey]}]}),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const inboxRelaySelections = withGetter(deriveEvents(repository, {filters: [{kinds: [RELAYS]}]}))
|
export const inboxRelaySelections = withGetter(deriveEvents(repository, {filters: [{kinds: [INBOX_RELAYS]}]}))
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
indexStore: inboxRelaySelectionsByPubkey,
|
indexStore: inboxRelaySelectionsByPubkey,
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import {derived} from 'svelte/store'
|
||||||
|
import {pubkey} from './session'
|
||||||
|
import {profilesByPubkey, loadProfile} from './profiles'
|
||||||
|
import {followsByPubkey, loadFollows} from './follows'
|
||||||
|
import {mutesByPubkey, loadMutes} from './mutes'
|
||||||
|
import {relaySelectionsByPubkey, inboxRelaySelectionsByPubkey, loadRelaySelections, loadInboxRelaySelections} from './relaySelections'
|
||||||
|
import {wotGraph} from './wot'
|
||||||
|
|
||||||
|
export const userProfile = derived(
|
||||||
|
[profilesByPubkey, pubkey],
|
||||||
|
([$profilesByPubkey, $pubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadProfile($pubkey)
|
||||||
|
|
||||||
|
return $profilesByPubkey.get($pubkey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userFollows = derived(
|
||||||
|
[followsByPubkey, pubkey],
|
||||||
|
([$followsByPubkey, $pubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadFollows($pubkey)
|
||||||
|
|
||||||
|
return $followsByPubkey.get($pubkey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userMutes = derived(
|
||||||
|
[mutesByPubkey, pubkey],
|
||||||
|
([$mutesByPubkey, $pubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadMutes($pubkey)
|
||||||
|
|
||||||
|
return $mutesByPubkey.get($pubkey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userRelaySelections = derived(
|
||||||
|
[relaySelectionsByPubkey, pubkey],
|
||||||
|
([$relaySelectionsByPubkey, $pubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadRelaySelections($pubkey)
|
||||||
|
|
||||||
|
return $relaySelectionsByPubkey.get($pubkey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userInboxRelaySelections = derived(
|
||||||
|
[inboxRelaySelectionsByPubkey, pubkey],
|
||||||
|
([$inboxRelaySelectionsByPubkey, $pubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadInboxRelaySelections($pubkey)
|
||||||
|
|
||||||
|
return $inboxRelaySelectionsByPubkey.get($pubkey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getUserWotScore = (tpk: string) => wotGraph.get().get(tpk) || 0
|
||||||
|
|
||||||
|
export const deriveUserWotScore = (tpk: string) => derived(wotGraph, $g => $g.get(tpk) || 0)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import Fuse from "fuse.js"
|
import Fuse from "fuse.js"
|
||||||
import type {IFuseOptions, FuseResult} from "fuse.js"
|
import type {IFuseOptions, FuseResult} from "fuse.js"
|
||||||
import {sortBy} from "@welshman/lib"
|
import {now, int, sortBy, DAY, HOUR, MINUTE} from "@welshman/lib"
|
||||||
|
|
||||||
export type SearchOptions<V, T> = {
|
export type SearchOptions<V, T> = {
|
||||||
getValue: (item: T) => V
|
getValue: (item: T) => V
|
||||||
@@ -24,7 +24,7 @@ export const createSearch = <V, T>(options: T[], opts: SearchOptions<V, T>): Sea
|
|||||||
const search = (term: string) => {
|
const search = (term: string) => {
|
||||||
opts.onSearch?.(term)
|
opts.onSearch?.(term)
|
||||||
|
|
||||||
let results = term ? fuse.search(term) : options.map(item => ({item, score: 1}) as FuseResult<T>)
|
let results = term ? fuse.search(term) : options.map(item => ({item}) as FuseResult<T>)
|
||||||
|
|
||||||
if (opts.sortFn) {
|
if (opts.sortFn) {
|
||||||
results = sortBy(opts.sortFn, results)
|
results = sortBy(opts.sortFn, results)
|
||||||
@@ -78,3 +78,27 @@ export const formatTimestampAsTime = (ts: number) => {
|
|||||||
|
|
||||||
return formatter.format(secondsToDate(ts))
|
return formatter.format(secondsToDate(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formatTimestampRelative = (ts: number) => {
|
||||||
|
let unit
|
||||||
|
let delta = now() - ts
|
||||||
|
if (delta < int(MINUTE)) {
|
||||||
|
unit = "second"
|
||||||
|
} else if (delta < int(HOUR)) {
|
||||||
|
unit = "minute"
|
||||||
|
delta = Math.round(delta / int(MINUTE))
|
||||||
|
} else if (delta < int(DAY, 2)) {
|
||||||
|
unit = "hour"
|
||||||
|
delta = Math.round(delta / int(HOUR))
|
||||||
|
} else {
|
||||||
|
unit = "day"
|
||||||
|
delta = Math.round(delta / int(DAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
const locale = new Intl.RelativeTimeFormat().resolvedOptions().locale
|
||||||
|
const formatter = new Intl.RelativeTimeFormat(locale, {
|
||||||
|
numeric: "auto",
|
||||||
|
})
|
||||||
|
|
||||||
|
return formatter.format(-delta, unit as Intl.RelativeTimeFormatUnit)
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,5 +83,3 @@ export const getWotScore = (pubkey: string, target: string) => {
|
|||||||
|
|
||||||
return follows.length - mutes.length
|
return follows.length - mutes.length
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getUserWotScore = (pubkey: string) => wotGraph.get().get(pubkey) || 0
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ export type Maybe<T> = T | undefined
|
|||||||
|
|
||||||
// Regular old utils
|
// Regular old utils
|
||||||
|
|
||||||
export const now = () => Math.round(Date.now() / 1000)
|
|
||||||
|
|
||||||
export const noop = (...args: unknown[]) => undefined
|
export const noop = (...args: unknown[]) => undefined
|
||||||
|
|
||||||
export const first = <T>(xs: T[], ...args: unknown[]) => xs[0]
|
export const first = <T>(xs: T[], ...args: unknown[]) => xs[0]
|
||||||
@@ -511,6 +509,30 @@ export const pushToMapKey = <K, T>(m: Map<K, T[]>, k: K, v: T) => {
|
|||||||
export const switcher = <T>(k: string, m: Record<string, T>) =>
|
export const switcher = <T>(k: string, m: Record<string, T>) =>
|
||||||
m[k] === undefined ? m.default : m[k]
|
m[k] === undefined ? m.default : m[k]
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
export const MINUTE = 60
|
||||||
|
|
||||||
|
export const HOUR = 60 * MINUTE
|
||||||
|
|
||||||
|
export const DAY = 24 * HOUR
|
||||||
|
|
||||||
|
export const WEEK = 7 * DAY
|
||||||
|
|
||||||
|
export const MONTH = 30 * DAY
|
||||||
|
|
||||||
|
export const QUARTER = 90 * DAY
|
||||||
|
|
||||||
|
export const YEAR = 365 * DAY
|
||||||
|
|
||||||
|
export const int = (unit: number, count = 1) => unit * count
|
||||||
|
|
||||||
|
export const now = () => Math.round(Date.now() / 1000)
|
||||||
|
|
||||||
|
export const ago = (unit: number, count = 1) => now() - int(unit, count)
|
||||||
|
|
||||||
|
export const ms = (seconds: number) => seconds * 1000
|
||||||
|
|
||||||
// Fetch
|
// Fetch
|
||||||
|
|
||||||
type FetchOpts = {
|
type FetchOpts = {
|
||||||
|
|||||||
Reference in New Issue
Block a user