Fetch, cache, and update profile data
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
import Service, { service } from '@ember/service';
|
import Service, { service } from '@ember/service';
|
||||||
import { tracked } from '@glimmer/tracking';
|
import { tracked } from '@glimmer/tracking';
|
||||||
|
import { from } from 'rxjs';
|
||||||
import { EventStore } from 'applesauce-core/event-store';
|
import { EventStore } from 'applesauce-core/event-store';
|
||||||
import { ProfileModel } from 'applesauce-core/models/profile';
|
import { ProfileModel } from 'applesauce-core/models/profile';
|
||||||
import { MailboxesModel } from 'applesauce-core/models/mailboxes';
|
import { MailboxesModel } from 'applesauce-core/models/mailboxes';
|
||||||
import { npubEncode } from 'applesauce-core/helpers/pointers';
|
import { npubEncode } from 'applesauce-core/helpers/pointers';
|
||||||
import { persistEventsToCache } from 'applesauce-core/helpers/event-cache';
|
import { persistEventsToCache } from 'applesauce-core/helpers/event-cache';
|
||||||
|
import { createEventLoaderForStore } from 'applesauce-loaders/loaders';
|
||||||
import { NostrIDB, openDB } from 'nostr-idb';
|
import { NostrIDB, openDB } from 'nostr-idb';
|
||||||
import {
|
import {
|
||||||
excludeRequiredRelays,
|
excludeRequiredRelays,
|
||||||
@@ -35,12 +37,14 @@ export default class NostrDataService extends Service {
|
|||||||
@tracked blossomServers = [];
|
@tracked blossomServers = [];
|
||||||
@tracked placePhotos = [];
|
@tracked placePhotos = [];
|
||||||
@tracked myContributionEvents = [];
|
@tracked myContributionEvents = [];
|
||||||
|
@tracked profiles = {};
|
||||||
|
|
||||||
_profileSub = null;
|
_profileSub = null;
|
||||||
_mailboxesSub = null;
|
_mailboxesSub = null;
|
||||||
_blossomSub = null;
|
_blossomSub = null;
|
||||||
_photosSub = null;
|
_photosSub = null;
|
||||||
_contributionsSub = null;
|
_contributionsSub = null;
|
||||||
|
_profileModelSubs = new Map();
|
||||||
|
|
||||||
_requestSub = null;
|
_requestSub = null;
|
||||||
_cachePromise = null;
|
_cachePromise = null;
|
||||||
@@ -81,6 +85,13 @@ export default class NostrDataService extends Service {
|
|||||||
maxBatchSize: 100,
|
maxBatchSize: 100,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set up the event loader so replaceable/event subscriptions auto-fetch
|
||||||
|
// from cache → relay hints → lookup relays with batching and dedup
|
||||||
|
createEventLoaderForStore(this.store, this.nostrRelay.pool, {
|
||||||
|
cacheRequest: (filters) => from(this.cache.query(filters)),
|
||||||
|
lookupRelays: DIRECTORY_RELAYS,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Feed events from the relay pool into the event store
|
// Feed events from the relay pool into the event store
|
||||||
@@ -218,6 +229,7 @@ export default class NostrDataService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.placePhotos = [];
|
this.placePhotos = [];
|
||||||
|
this._clearProfileSubs();
|
||||||
|
|
||||||
if (!place || !place.osmId || !place.osmType) {
|
if (!place || !place.osmId || !place.osmType) {
|
||||||
return;
|
return;
|
||||||
@@ -235,6 +247,8 @@ export default class NostrDataService extends Service {
|
|||||||
])
|
])
|
||||||
.subscribe((events) => {
|
.subscribe((events) => {
|
||||||
this.placePhotos = events;
|
this.placePhotos = events;
|
||||||
|
const pubkeys = [...new Set(events.map((e) => e.pubkey))];
|
||||||
|
this.loadProfiles(pubkeys);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -331,6 +345,33 @@ export default class NostrDataService extends Service {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadProfiles(pubkeys) {
|
||||||
|
const newPubkeys = pubkeys.filter(
|
||||||
|
(pk) => pk && !this._profileModelSubs.has(pk)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const pubkey of newPubkeys) {
|
||||||
|
const sub = this.store
|
||||||
|
.model(ProfileModel, pubkey)
|
||||||
|
.subscribe((profileContent) => {
|
||||||
|
this.profiles = { ...this.profiles, [pubkey]: profileContent };
|
||||||
|
});
|
||||||
|
this._profileModelSubs.set(pubkey, sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getProfile(pubkey) {
|
||||||
|
return this.profiles[pubkey];
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearProfileSubs() {
|
||||||
|
for (const sub of this._profileModelSubs.values()) {
|
||||||
|
sub.unsubscribe();
|
||||||
|
}
|
||||||
|
this._profileModelSubs.clear();
|
||||||
|
this.profiles = {};
|
||||||
|
}
|
||||||
|
|
||||||
async loadProfile(pubkey) {
|
async loadProfile(pubkey) {
|
||||||
if (!pubkey) return;
|
if (!pubkey) return;
|
||||||
|
|
||||||
@@ -466,6 +507,7 @@ export default class NostrDataService extends Service {
|
|||||||
this._contributionsSub.unsubscribe();
|
this._contributionsSub.unsubscribe();
|
||||||
this._contributionsSub = null;
|
this._contributionsSub = null;
|
||||||
}
|
}
|
||||||
|
this._clearProfileSubs();
|
||||||
}
|
}
|
||||||
|
|
||||||
willDestroy() {
|
willDestroy() {
|
||||||
|
|||||||
@@ -105,6 +105,7 @@
|
|||||||
"@noble/hashes": "^2.3.0",
|
"@noble/hashes": "^2.3.0",
|
||||||
"@waysidemapping/pinhead": "^15.25.0",
|
"@waysidemapping/pinhead": "^15.25.0",
|
||||||
"applesauce-core": "^6.2.0",
|
"applesauce-core": "^6.2.0",
|
||||||
|
"applesauce-loaders": "^6.2.0",
|
||||||
"applesauce-relay": "^6.2.1",
|
"applesauce-relay": "^6.2.1",
|
||||||
"applesauce-signers": "^6.2.2",
|
"applesauce-signers": "^6.2.2",
|
||||||
"blurhash": "^2.0.5",
|
"blurhash": "^2.0.5",
|
||||||
|
|||||||
Generated
+15
@@ -20,6 +20,9 @@ importers:
|
|||||||
applesauce-core:
|
applesauce-core:
|
||||||
specifier: ^6.2.0
|
specifier: ^6.2.0
|
||||||
version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
|
version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
|
||||||
|
applesauce-loaders:
|
||||||
|
specifier: ^6.2.0
|
||||||
|
version: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
|
||||||
applesauce-relay:
|
applesauce-relay:
|
||||||
specifier: ^6.2.1
|
specifier: ^6.2.1
|
||||||
version: 6.2.1(supports-color@10.2.2)(typescript@5.9.3)
|
version: 6.2.1(supports-color@10.2.2)(typescript@5.9.3)
|
||||||
@@ -2636,6 +2639,9 @@ packages:
|
|||||||
applesauce-core@6.2.0:
|
applesauce-core@6.2.0:
|
||||||
resolution: {integrity: sha512-O6AlVyzqcuIhTOIuexm6UWmx7mRIa2D98gJP7K7vFGf90YdtvSH78AsKQWZXJ0Pk/K14at+9zkwfCkFr7ghgNw==}
|
resolution: {integrity: sha512-O6AlVyzqcuIhTOIuexm6UWmx7mRIa2D98gJP7K7vFGf90YdtvSH78AsKQWZXJ0Pk/K14at+9zkwfCkFr7ghgNw==}
|
||||||
|
|
||||||
|
applesauce-loaders@6.2.0:
|
||||||
|
resolution: {integrity: sha512-isU2BuoVFhugv4WxdbUFrqm7mCNgsGrMU4BYcNqMm8qAVpVb3L7K3I1hlkIZWwOvNTkhoYO/u0utgwnkQj4Hrg==}
|
||||||
|
|
||||||
applesauce-relay@6.2.1:
|
applesauce-relay@6.2.1:
|
||||||
resolution: {integrity: sha512-YIUHEtL2Fl5FZjeKYe/IuwL3OnMUNP2j4ydSr3iZDeHEZSEda4d1PoChefiNhtjE/U/F5OBHEbAX1zCHRZoxpg==}
|
resolution: {integrity: sha512-YIUHEtL2Fl5FZjeKYe/IuwL3OnMUNP2j4ydSr3iZDeHEZSEda4d1PoChefiNhtjE/U/F5OBHEbAX1zCHRZoxpg==}
|
||||||
|
|
||||||
@@ -9354,6 +9360,15 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
|
applesauce-loaders@6.2.0(supports-color@10.2.2)(typescript@5.9.3):
|
||||||
|
dependencies:
|
||||||
|
applesauce-core: 6.2.0(supports-color@10.2.2)(typescript@5.9.3)
|
||||||
|
nanoid: 5.1.9
|
||||||
|
rxjs: 7.8.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
|
||||||
applesauce-relay@6.2.1(supports-color@10.2.2)(typescript@5.9.3):
|
applesauce-relay@6.2.1(supports-color@10.2.2)(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 2.3.0
|
'@noble/hashes': 2.3.0
|
||||||
|
|||||||
Reference in New Issue
Block a user