aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/messages.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/messages.js')
-rw-r--r--src/features/messages.js31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 899ee1d..bbec23e 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -645,7 +645,13 @@ export function messagesFeature(ctx) {
if (!wallet.mnemonic && !wallet.xprv && !wallet.xpub) return;
profilesWarmed = true;
const cached = profilesDisk();
- for (const [pk, p] of Object.entries(cached)) if (!profiles.has(pk)) profiles.set(pk, p);
+ // (a row asked for before the cache opened — still loading, or a miss
+ // while offline — gives way to the remembered face; a kind 0 that
+ // really named nothing keeps its say)
+ for (const [pk, p] of Object.entries(cached)) {
+ const cur = profiles.get(pk);
+ if (!cur || (!cur.name && !cur.picture && !cur.eventAt)) profiles.set(pk, p);
+ }
// someone known to have no face paints their punk from the first frame,
// instead of a blank circle that turns into one when the relays answer
for (const [pk, t] of Object.entries(facelessDisk())) {
@@ -1176,6 +1182,10 @@ export function messagesFeature(ctx) {
folded: null,
controlEntries: [],
guestEntries: [],
+ // the wraps this room opened: a room rebuilt with fresher keys hands
+ // them back to seenWraps, or its new subscription would skip the
+ // replay and fold without them
+ wrapIds: new Set(),
members: new Map(),
byChannel: new Map(),
edits: new Map(),
@@ -1251,6 +1261,7 @@ export function messagesFeature(ctx) {
subscribeOn(room.relays, { kinds: [1059], authors: [room.control.pk], limit: 500 }, (wrap) => {
if (seenWraps.has(wrap.id)) return;
seenWraps.add(wrap.id);
+ room.wrapIds.add(wrap.id);
openWrapBg(wrap, room.control, (opened) => {
if (!opened || opened.rumor.kind !== 3308) return;
room.controlEntries.push(opened);
@@ -1260,6 +1271,7 @@ export function messagesFeature(ctx) {
subscribeOn(room.relays, { kinds: [1059], authors: [room.guestbook.pk], limit: 500 }, (wrap) => {
if (seenWraps.has(wrap.id)) return;
seenWraps.add(wrap.id);
+ room.wrapIds.add(wrap.id);
openWrapBg(wrap, room.guestbook, (opened) => {
if (!opened) return;
room.guestEntries.push(opened);
@@ -1286,6 +1298,7 @@ export function messagesFeature(ctx) {
const u = subscribeOn(room.relays, { kinds: [1059, 21059], authors: [stream.pk], limit: 200 }, (wrap) => {
if (seenWraps.has(wrap.id)) return;
seenWraps.add(wrap.id);
+ room.wrapIds.add(wrap.id);
openWrapBg(wrap, stream, (opened) => {
if (!opened) return;
onChat(room, id, opened);
@@ -2140,7 +2153,11 @@ export function messagesFeature(ctx) {
// public data, and Back lands on the app's own front door.
if (urlFeed) {
ui.pubProf = true; ui.chatOpen = true; ui.msgView = 'feed';
+ // hold the frame until the URL's feed is chosen: painted a tick early,
+ // the feed view would open (and fetch) the default feed first
+ ui.pubFeedPending = true;
setTimeout(() => {
+ ui.pubFeedPending = null;
if (openFeedUrl(urlFeed.path, urlFeed.search)) return;
ui.pubProf = null; ui.chatOpen = false; ui.msgView = null; // not a feed we know: the front door
render();
@@ -2506,7 +2523,11 @@ export function messagesFeature(ctx) {
if (!newer && !fill) continue;
Object.assign(have, jmSubset(jm), { name: have.name || jm.name, relays: have.relays && have.relays.length ? have.relays : jm.relays });
const stale = rooms.get(have.community_id); // rebuilt with the new keys on next open
- if (stale) { for (const u of stale.unsubs || []) { try { u(); } catch {} } rooms.delete(have.community_id); }
+ if (stale) {
+ for (const u of stale.unsubs || []) { try { u(); } catch {} }
+ for (const id of stale.wrapIds || []) seenWraps.delete(id);
+ rooms.delete(have.community_id);
+ }
changed = true;
continue;
}
@@ -4789,8 +4810,9 @@ export function messagesFeature(ctx) {
const curateFeed = (evs) => { const lang = getLang(); return evs.filter((e) => !isMachinePost(e.content) && inLanguage(e.content, lang)); };
async function popularPass(extra, merge, c, def) {
// Only the default public feed shares a snapshot. Custom relays and older
- // pages keep their own queries. A static/offline install falls back quickly.
- if (extra.until == null && !feedRelays(def)) {
+ // pages keep their own queries. A static/offline install falls back quickly;
+ // the single file opened from a disk has no server to ask at all.
+ if (extra.until == null && !feedRelays(def) && /^https?:$/.test(location.protocol)) {
try {
const response = await fetch('/api/feed', { signal: AbortSignal.timeout(1500) });
if (!response.ok || !response.headers.get('content-type')?.includes('application/json')) throw new Error('No feed cache');
@@ -12816,6 +12838,7 @@ export function messagesFeature(ctx) {
ctx.brandHeader(false),
h('div', { class: 'card row gap6', style: 'justify-content:center;align-items:center;padding:16px' },
h('span', { class: 'spinner sm' }), h('span', { class: 'small faint' }, t('noteRefLoading'))));
+ if (ui.pubFeedPending) return h('div', { class: 'col', style: 'gap:16px' }, ctx.brandHeader(false));
if (ui.pubProfPending) return h('div', { class: 'col', style: 'gap:16px' },
ctx.brandHeader(false),
h('div', { class: 'card col', style: 'gap:12px' },