mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Fix space notifications
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -34,7 +34,7 @@
|
|||||||
"@welshman/content": "~0.0.13",
|
"@welshman/content": "~0.0.13",
|
||||||
"@welshman/dvm": "~0.0.11",
|
"@welshman/dvm": "~0.0.11",
|
||||||
"@welshman/feeds": "~0.0.26",
|
"@welshman/feeds": "~0.0.26",
|
||||||
"@welshman/lib": "~0.0.30",
|
"@welshman/lib": "~0.0.32",
|
||||||
"@welshman/net": "~0.0.41",
|
"@welshman/net": "~0.0.41",
|
||||||
"@welshman/signer": "~0.0.16",
|
"@welshman/signer": "~0.0.16",
|
||||||
"@welshman/store": "~0.0.13",
|
"@welshman/store": "~0.0.13",
|
||||||
@@ -4715,9 +4715,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@welshman/lib": {
|
"node_modules/@welshman/lib": {
|
||||||
"version": "0.0.30",
|
"version": "0.0.32",
|
||||||
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.32.tgz",
|
||||||
"integrity": "sha512-UeYFh9H3m7NfsokyaOeOCAdp4dg2uv20+XtkDxlaLVMMJDtuePBLJBYQJKuxMavGAJURr4pXt2Xna53hN/R5Lg==",
|
"integrity": "sha512-mQ3vG2ttsdlzQm9bkvxBsrjxHVt/3JgQWp9o32ep5H8s1sVbdjG0adtuSv0xrkrZg5zB0p0P3jRb7LXgsq89FA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scure/base": "^1.1.6",
|
"@scure/base": "^1.1.6",
|
||||||
|
|||||||
@@ -62,11 +62,11 @@
|
|||||||
"@welshman/content": "~0.0.13",
|
"@welshman/content": "~0.0.13",
|
||||||
"@welshman/dvm": "~0.0.11",
|
"@welshman/dvm": "~0.0.11",
|
||||||
"@welshman/feeds": "~0.0.26",
|
"@welshman/feeds": "~0.0.26",
|
||||||
"@welshman/lib": "~0.0.30",
|
"@welshman/lib": "~0.0.33",
|
||||||
"@welshman/net": "~0.0.41",
|
"@welshman/net": "~0.0.41",
|
||||||
"@welshman/signer": "~0.0.16",
|
"@welshman/signer": "~0.0.16",
|
||||||
"@welshman/store": "~0.0.13",
|
"@welshman/store": "~0.0.13",
|
||||||
"@welshman/util": "~0.0.49",
|
"@welshman/util": "~0.0.50",
|
||||||
"daisyui": "^4.12.10",
|
"daisyui": "^4.12.10",
|
||||||
"date-picker-svelte": "^2.13.0",
|
"date-picker-svelte": "^2.13.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
|||||||
@@ -5,8 +5,15 @@ import {repository, pubkey} from "@welshman/app"
|
|||||||
import {prop, max, sortBy, assoc, lt, now} from "@welshman/lib"
|
import {prop, max, sortBy, assoc, lt, now} from "@welshman/lib"
|
||||||
import type {Filter, TrustedEvent} from "@welshman/util"
|
import type {Filter, TrustedEvent} from "@welshman/util"
|
||||||
import {DIRECT_MESSAGE, MESSAGE, THREAD, COMMENT} from "@welshman/util"
|
import {DIRECT_MESSAGE, MESSAGE, THREAD, COMMENT} from "@welshman/util"
|
||||||
import {makeSpacePath} from "@app/routes"
|
import {makeSpacePath, makeThreadPath, makeRoomPath} from "@app/routes"
|
||||||
import {LEGACY_THREAD, deriveEventsForUrl, getMembershipUrls, userMembership} from "@app/state"
|
import {
|
||||||
|
LEGACY_THREAD,
|
||||||
|
getEventsForUrl,
|
||||||
|
deriveEventsForUrl,
|
||||||
|
getMembershipUrls,
|
||||||
|
userRoomsByUrl,
|
||||||
|
repositoryStore,
|
||||||
|
} from "@app/state"
|
||||||
|
|
||||||
// Checked state
|
// Checked state
|
||||||
|
|
||||||
@@ -62,17 +69,30 @@ export const deriveNotification = (path: string, filters: Filter[], url?: string
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const spacesNotifications = derived(
|
export const spacesNotifications = derived(
|
||||||
[pubkey, checked, userMembership, deriveEvents(repository, {filters: SPACE_FILTERS})],
|
[pubkey, checked, userRoomsByUrl, repositoryStore],
|
||||||
([$pubkey, $checked, $userMembership, $events]) => {
|
([$pubkey, $checked, $userRoomsByUrl, $repository]) => {
|
||||||
return getMembershipUrls($userMembership)
|
const hasNotification = (url: string, path: string, filters: Filter[]) => {
|
||||||
.filter(url => {
|
const lastChecked = max([$checked["*"], $checked[path]])
|
||||||
const path = makeSpacePath(url)
|
const events = getEventsForUrl($repository, url, filters)
|
||||||
const lastChecked = max([$checked["*"], $checked[path]])
|
|
||||||
const [latestEvent] = sortBy($e => -$e.created_at, $events)
|
|
||||||
|
|
||||||
return latestEvent?.pubkey !== $pubkey && lt(lastChecked, latestEvent?.created_at)
|
return getNotification($pubkey, lastChecked, events)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from($userRoomsByUrl.entries())
|
||||||
|
.filter(([url, rooms]) => {
|
||||||
|
if (hasNotification(url, makeThreadPath(url), THREAD_FILTERS)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const room of rooms) {
|
||||||
|
if (hasNotification(url, makeRoomPath(url, room), [{kinds: [MESSAGE], "#h": [room]}])) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
})
|
})
|
||||||
.map(url => makeSpacePath(url))
|
.map(([url]) => makeSpacePath(url))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {MESSAGE, DELETE, THREAD, COMMENT} from "@welshman/util"
|
|||||||
import type {SubscribeRequestWithHandlers, Subscription} from "@welshman/net"
|
import type {SubscribeRequestWithHandlers, Subscription} from "@welshman/net"
|
||||||
import {SubscriptionEvent} from "@welshman/net"
|
import {SubscriptionEvent} from "@welshman/net"
|
||||||
import type {AppSyncOpts} from "@welshman/app"
|
import type {AppSyncOpts} from "@welshman/app"
|
||||||
import {subscribe, load, pull, hasNegentropy} from "@welshman/app"
|
import {subscribe, repository, load, pull, hasNegentropy} from "@welshman/app"
|
||||||
import {userRoomsByUrl, LEGACY_MESSAGE, GENERAL, getEventsForUrl} from "@app/state"
|
import {userRoomsByUrl, LEGACY_MESSAGE, GENERAL, getEventsForUrl} from "@app/state"
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
@@ -16,7 +16,7 @@ export const pullConservatively = ({relays, filters}: AppSyncOpts) => {
|
|||||||
// Since pulling from relays without negentropy is expensive, limit how many
|
// Since pulling from relays without negentropy is expensive, limit how many
|
||||||
// duplicates we repeatedly download
|
// duplicates we repeatedly download
|
||||||
for (const url of dumb) {
|
for (const url of dumb) {
|
||||||
const events = getEventsForUrl(url, filters)
|
const events = getEventsForUrl(repository, url, filters)
|
||||||
|
|
||||||
if (events.length > 100) {
|
if (events.length > 100) {
|
||||||
filters = filters.map(assoc("since", events[10]!.created_at))
|
filters = filters.map(assoc("since", events[10]!.created_at))
|
||||||
|
|||||||
@@ -15,8 +15,15 @@ export const makeChatPath = (pubkeys: string[]) => `/chat/${makeChatId(pubkeys)}
|
|||||||
|
|
||||||
export const makeRoomPath = (url: string, room: string) => `/spaces/${encodeRelay(url)}/${room}`
|
export const makeRoomPath = (url: string, room: string) => `/spaces/${encodeRelay(url)}/${room}`
|
||||||
|
|
||||||
export const makeThreadPath = (url: string, eventId: string) =>
|
export const makeThreadPath = (url: string, eventId?: string) => {
|
||||||
`/spaces/${encodeRelay(url)}/threads/${eventId}`
|
let path = `/spaces/${encodeRelay(url)}/threads`
|
||||||
|
|
||||||
|
if (eventId) {
|
||||||
|
path += "/" + eventId
|
||||||
|
}
|
||||||
|
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
export const getPrimaryNavItem = ($page: Page) => $page.route?.id?.split("/")[1]
|
export const getPrimaryNavItem = ($page: Page) => $page.route?.id?.split("/")[1]
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import {
|
|||||||
makeRouter,
|
makeRouter,
|
||||||
tracker,
|
tracker,
|
||||||
makeTrackerStore,
|
makeTrackerStore,
|
||||||
|
makeRepositoryStore,
|
||||||
relay,
|
relay,
|
||||||
getSession,
|
getSession,
|
||||||
getSigner,
|
getSigner,
|
||||||
@@ -208,6 +209,8 @@ export const ensureUnwrapped = async (event: TrustedEvent) => {
|
|||||||
|
|
||||||
export const trackerStore = makeTrackerStore()
|
export const trackerStore = makeTrackerStore()
|
||||||
|
|
||||||
|
export const repositoryStore = makeRepositoryStore()
|
||||||
|
|
||||||
export const deriveEvent = (idOrAddress: string, hints: string[] = []) => {
|
export const deriveEvent = (idOrAddress: string, hints: string[] = []) => {
|
||||||
let attempted = false
|
let attempted = false
|
||||||
|
|
||||||
@@ -251,7 +254,7 @@ export const getUrlsForEvent = derived([trackerStore, thunks], ([$tracker, $thun
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getEventsForUrl = (url: string, filters: Filter[]) => {
|
export const getEventsForUrl = (repository: Repository, url: string, filters: Filter[]) => {
|
||||||
const $getUrlsForEvent = get(getUrlsForEvent)
|
const $getUrlsForEvent = get(getUrlsForEvent)
|
||||||
const $events = repository.query(filters)
|
const $events = repository.query(filters)
|
||||||
|
|
||||||
@@ -604,19 +607,24 @@ export const userMembership = withGetter(
|
|||||||
|
|
||||||
export const userRoomsByUrl = withGetter(
|
export const userRoomsByUrl = withGetter(
|
||||||
derived(userMembership, $userMembership => {
|
derived(userMembership, $userMembership => {
|
||||||
|
const tags = getListTags($userMembership)
|
||||||
const $userRoomsByUrl = new Map<string, Set<string>>()
|
const $userRoomsByUrl = new Map<string, Set<string>>()
|
||||||
|
|
||||||
for (const [_, room, url] of getGroupTags(getListTags($userMembership))) {
|
for (const [_, room, url] of getGroupTags(tags)) {
|
||||||
addToMapKey($userRoomsByUrl, url, room)
|
addToMapKey($userRoomsByUrl, url, room)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const url of getRelayTagValues(tags)) {
|
||||||
|
addToMapKey($userRoomsByUrl, url, GENERAL)
|
||||||
|
}
|
||||||
|
|
||||||
return $userRoomsByUrl
|
return $userRoomsByUrl
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const deriveUserRooms = (url: string) =>
|
export const deriveUserRooms = (url: string) =>
|
||||||
derived(userRoomsByUrl, $userRoomsByUrl =>
|
derived(userRoomsByUrl, $userRoomsByUrl =>
|
||||||
sortBy(roomComparator(url), uniq(Array.from($userRoomsByUrl.get(url) || []).concat(GENERAL))),
|
sortBy(roomComparator(url), uniq(Array.from($userRoomsByUrl.get(url) || []))),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const deriveOtherRooms = (url: string) =>
|
export const deriveOtherRooms = (url: string) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user