fix: normalize federated asset URLs in explore and social stores
Resolve remote instance avatars and space icons at the data boundary so they render correctly instead of 404ing against the home instance.
This commit is contained in:
@@ -335,12 +335,14 @@ function handleEvent(origin: string, event: ServerEvent): void {
|
||||
// ─── Social events (all origins — federation) ──────────────────────────
|
||||
|
||||
case 'friend_request_received': {
|
||||
if (!isHome && event.request.user) normalizeUserAssets(event.request.user, origin);
|
||||
const { addIncomingRequest } = useSocialStore.getState();
|
||||
addIncomingRequest(event.request, origin);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'friend_request_accepted': {
|
||||
if (!isHome) normalizeUserAssets(event.friend, origin);
|
||||
const { addFriendFromAccepted } = useSocialStore.getState();
|
||||
addFriendFromAccepted(event.friend, event.requestId, origin);
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { create } from 'zustand';
|
||||
import type { ExploreSpace, JoinRequest, SpaceWithChannelsAndMembers } from '@backspace/shared';
|
||||
import { api } from '../api/client';
|
||||
import { resolveAssetUrl } from '../utils/assetUrls';
|
||||
import { useInstanceStore } from './instanceStore';
|
||||
import { useSpaceStore } from './spaceStore';
|
||||
|
||||
@@ -89,6 +90,9 @@ export const useExploreStore = create<ExploreState>((set, get) => ({
|
||||
const key = `${space.id}:${origin}`;
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
if (origin && space.icon) {
|
||||
space.icon = resolveAssetUrl(space.icon, origin) ?? space.icon;
|
||||
}
|
||||
allSpaces.push({ ...space, _instanceOrigin: origin, joined: space.joined ?? false });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { create } from 'zustand';
|
||||
import type { Friend, FriendRequest, User } from '@backspace/shared';
|
||||
import { api } from '../api/client';
|
||||
import { useInstanceStore } from './instanceStore';
|
||||
import { normalizeUserAssets } from '../utils/assetUrls';
|
||||
|
||||
// ─── Tagged types (origin tracking for federation) ───────────────────────────
|
||||
|
||||
@@ -66,6 +67,7 @@ export const useSocialStore = create<SocialState>((set, get) => ({
|
||||
const key = `${friend.id}:${origin}`;
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
if (origin) normalizeUserAssets(friend, origin);
|
||||
allFriends.push({ ...friend, _instanceOrigin: origin });
|
||||
}
|
||||
}
|
||||
@@ -99,6 +101,7 @@ export const useSocialStore = create<SocialState>((set, get) => ({
|
||||
const key = `${request.id}:${origin}`;
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
if (origin && request.user) normalizeUserAssets(request.user, origin);
|
||||
allRequests.push({ ...request, _instanceOrigin: origin });
|
||||
}
|
||||
}
|
||||
@@ -217,22 +220,30 @@ export const useSocialStore = create<SocialState>((set, get) => ({
|
||||
const instances = useInstanceStore.getState().instances;
|
||||
const connectedInstances = instances.filter(i => i.status === 'connected');
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
api.social.search(query),
|
||||
...connectedInstances.map(inst => inst.api.social.search(query)),
|
||||
]);
|
||||
// Pair each promise with its origin for asset normalization
|
||||
const searches: { promise: Promise<User[]>; origin: string }[] = [
|
||||
{ promise: api.social.search(query), origin: '' },
|
||||
...connectedInstances.map(inst => ({
|
||||
promise: inst.api.social.search(query),
|
||||
origin: inst.origin,
|
||||
})),
|
||||
];
|
||||
|
||||
const results = await Promise.allSettled(searches.map(s => s.promise));
|
||||
|
||||
const allUsers: User[] = [];
|
||||
const seen = new Set<string>();
|
||||
|
||||
for (const result of results) {
|
||||
if (result.status !== 'fulfilled') continue;
|
||||
results.forEach((result, i) => {
|
||||
if (result.status !== 'fulfilled') return;
|
||||
const origin = searches[i]!.origin;
|
||||
for (const user of result.value) {
|
||||
if (seen.has(user.id)) continue;
|
||||
seen.add(user.id);
|
||||
if (origin) normalizeUserAssets(user, origin);
|
||||
allUsers.push(user);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return allUsers;
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user