chore: add system docs, specs, and misc updates from other sessions

- Add complete docs/systems/ reference (18 system docs)
- Add federation relay status doc and prior spec/plan docs
- Remove superseded docs/federation-dm-s2s.md (replaced by docs/systems/federation.md)
- CLAUDE.md updates
- Minor fixes in social.ts, types.ts, AddDmMemberModal, NewDmModal, UserSettings
This commit is contained in:
Jannis Braun
2026-03-31 03:40:34 +02:00
parent 70678ff198
commit a3a7527c9e
25 changed files with 8414 additions and 1243 deletions
+1
View File
@@ -18,6 +18,7 @@ import { sanitizeUser } from '../utils/sanitize.js';
function buildProfileSnapshot(user: typeof schema.users.$inferSelect): FederationRelayProfileSnapshot {
return {
username: user.username ?? null,
displayName: user.displayName ?? null,
avatar: user.avatar ?? null,
avatarColor: user.avatarColor ?? null,
+1
View File
@@ -797,6 +797,7 @@ export interface FederationGroupPayload {
}
export interface FederationRelayProfileSnapshot {
username?: string | null;
displayName?: string | null;
avatar?: string | null;
avatarColor?: string | null;
@@ -7,7 +7,7 @@ import { useSpaceStore } from '../../stores/spaceStore';
import { useAuthStore } from '../../stores/authStore';
import { useSocialStore } from '../../stores/socialStore';
import { api } from '../../api/client';
import { isSelf } from '../../utils/identity';
import { isSelf, parseFederatedUsername } from '../../utils/identity';
export function AddDmMemberModal() {
const [query, setQuery] = useState('');
@@ -150,7 +150,7 @@ export function AddDmMemberModal() {
key={f.id}
className="flex items-center gap-1 px-2.5 py-1 rounded-full text-[12px] bg-accent-mint/15 text-accent-mint"
>
{f.displayName ?? f.username}
{f.displayName ?? parseFederatedUsername(f.username).baseName}
<button
onClick={() => removeFriend(f.id)}
className="opacity-60 hover:opacity-100 transition-opacity text-[14px] leading-none"
@@ -193,6 +193,8 @@ export function AddDmMemberModal() {
const isInDm = currentMemberIds.has(friend.id);
const isSelected = selected.has(friend.id);
const atCapacity = !isSelected && selected.size >= remainingSlots;
const { baseName, domain } = parseFederatedUsername(friend.username);
const friendDisplayName = friend.displayName ?? baseName;
return (
<button
@@ -209,23 +211,18 @@ export function AddDmMemberModal() {
>
<Avatar
src={friend.avatar}
name={friend.displayName ?? friend.username}
name={friendDisplayName}
size={30}
status={friend.status as any}
userId={friend.homeUserId ?? friend.id}
avatarColor={friend.avatarColor}
/>
<div className="flex-1 min-w-0">
<div className="text-[13px] font-medium text-txt-primary truncate">
{friend.displayName ?? friend.username}
{friendDisplayName}
</div>
<div className="text-[11px] text-txt-tertiary truncate">
{isInDm
? 'Already in this DM'
: friend.username.includes('@')
? `@${friend.username}`
: friend._instanceOrigin
? `@${friend.username}@${(() => { try { return new URL(friend._instanceOrigin).host; } catch { return friend._instanceOrigin; } })()}`
: `@${friend.username}`}
{isInDm ? 'Already in this DM' : `@${friend.username}`}
</div>
</div>
{!isInDm && (
@@ -6,6 +6,7 @@ import { useUIStore } from '../../stores/uiStore';
import { useSpaceStore, getApiForOrigin, resolveUserOrigin } from '../../stores/spaceStore';
import { api } from '../../api/client';
import type { User } from '@backspace/shared';
import { parseFederatedUsername } from '../../utils/identity';
export function NewDmModal() {
const [query, setQuery] = useState('');
@@ -103,21 +104,25 @@ export function NewDmModal() {
<div className="py-4 text-center text-txt-tertiary text-[14px]">No users found</div>
)}
{results.map((user) => (
<button
key={user.id}
onClick={() => handleSelectUser(user)}
className="w-full flex items-center gap-3 px-3 py-2 rounded-[4px] hover:bg-interactive-hover transition-colors text-left"
>
<Avatar src={user.avatar} name={user.displayName ?? user.username} size={36} status={user.status as any} userId={user.homeUserId ?? user.id} />
<div className="flex-1 min-w-0">
<div className="text-[14px] font-medium text-txt-primary truncate">
{user.displayName ?? user.username}
{results.map((user) => {
const { baseName } = parseFederatedUsername(user.username);
const displayName = user.displayName ?? baseName;
return (
<button
key={user.id}
onClick={() => handleSelectUser(user)}
className="w-full flex items-center gap-3 px-3 py-2 rounded-[4px] hover:bg-interactive-hover transition-colors text-left"
>
<Avatar src={user.avatar} name={displayName} size={36} status={user.status as any} userId={user.homeUserId ?? user.id} avatarColor={user.avatarColor} />
<div className="flex-1 min-w-0">
<div className="text-[14px] font-medium text-txt-primary truncate">
{displayName}
</div>
<div className="text-[12px] text-txt-tertiary truncate">@{user.username}</div>
</div>
<div className="text-[12px] text-txt-tertiary truncate">@{user.username}</div>
</div>
</button>
))}
</button>
);
})}
</div>
</div>
</Modal>
@@ -109,6 +109,7 @@ export function UserSettingsModal() {
name={user?.displayName || user?.username || ''}
size={36}
userId={user?.id}
avatarColor={user?.avatarColor}
/>
<div className="min-w-0">
<div className="text-sm font-medium text-txt-primary truncate">{user?.displayName || user?.username}</div>
@@ -160,6 +161,7 @@ export function UserSettingsModal() {
name={user?.displayName || user?.username || ''}
size={36}
userId={user?.id}
avatarColor={user?.avatarColor}
/>
<div className="min-w-0">
<div className="text-sm font-medium text-txt-primary truncate">{user?.displayName || user?.username}</div>