fix(trash board): keep hidden special boards on canonical BSO identity

Resolve trash and other hidden special board routes to their canonical BSO
address and public key instead of stale directory aliases.
This commit is contained in:
Tommaso Casaburi
2026-07-07 23:45:13 +07:00
parent 6c9c57794c
commit e2dc9413a0
4 changed files with 61 additions and 1 deletions
@@ -214,6 +214,22 @@ describe('BoardHeader', () => {
expect(container.textContent).toContain(TRASH_BOARD_ADDRESS); expect(container.textContent).toContain(TRASH_BOARD_ADDRESS);
}); });
it('keeps hidden special board subtitles on the canonical BSO address', async () => {
testState.directories = [{ address: 'off-topic.eth', title: '/trash/ - Off-topic' }];
testState.resolvedAddress = TRASH_BOARD_ADDRESS;
testState.stableCommunity = {
address: 'off-topic.eth',
shortAddress: 'off-topic.eth',
title: '/trash/ - Off-topic',
};
await renderHeader('/trash');
expect(container.textContent).toContain(TRASH_BOARD_TITLE);
expect(container.textContent).toContain(TRASH_BOARD_ADDRESS);
expect(container.textContent).not.toContain('off-topic.eth');
});
it('renders the board loading indicator while online status is still loading', async () => { it('renders the board loading indicator while online status is still loading', async () => {
testState.useIsCommunityOfflineValue = { testState.useIsCommunityOfflineValue = {
isOffline: false, isOffline: false,
+1 -1
View File
@@ -92,7 +92,7 @@ const BoardHeader = () => {
? '' ? ''
: isInDirectoryListView : isInDirectoryListView
? t('directory_subtitle', { boardIdentifier: params.boardIdentifier }) ? t('directory_subtitle', { boardIdentifier: params.boardIdentifier })
: `${address || communityAddress || ''}`; : `${specialBoard?.address || address || communityAddress || ''}`;
return ( return (
<div className={`${styles.content} ${shouldShowSnow() ? styles.garland : ''}`}> <div className={`${styles.content} ${shouldShowSnow() ? styles.garland : ''}`}>
@@ -3,6 +3,7 @@ import { createElement } from 'react';
import { createRoot, type Root } from 'react-dom/client'; import { createRoot, type Root } from 'react-dom/client';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { useCommunityIdentifier, useCommunityIdentifiers } from '../use-community-identifiers'; import { useCommunityIdentifier, useCommunityIdentifiers } from '../use-community-identifiers';
import { TRASH_BOARD_ADDRESS, TRASH_BOARD_PUBLIC_KEY } from '../../lib/special-boards';
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true; (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>; const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>;
@@ -99,6 +100,36 @@ describe('useCommunityIdentifier', () => {
}); });
}); });
it('keeps hidden special board routes on the canonical BSO identity', async () => {
testState.address = TRASH_BOARD_ADDRESS;
testState.directories = [
{
address: 'off-topic.eth',
directoryCode: 'trash',
publicKey: 'stale-directory-key',
title: '/trash/ - Off-topic',
},
];
await renderHarness(createElement(SingleHarness));
expect(latestIdentifier).toEqual({
name: TRASH_BOARD_ADDRESS,
publicKey: TRASH_BOARD_PUBLIC_KEY,
});
});
it('canonicalizes hidden special board aliases before loading communities', async () => {
testState.address = 'off-topic.eth';
await renderHarness(createElement(SingleHarness));
expect(latestIdentifier).toEqual({
name: TRASH_BOARD_ADDRESS,
publicKey: TRASH_BOARD_PUBLIC_KEY,
});
});
it('keeps unlisted domain routes as direct community names', async () => { it('keeps unlisted domain routes as direct community names', async () => {
testState.address = 'unlisted-board.bso'; testState.address = 'unlisted-board.bso';
+13
View File
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
import type { CommunityIdentifier } from '@bitsocial/bitsocial-react-hooks'; import type { CommunityIdentifier } from '@bitsocial/bitsocial-react-hooks';
import { findDirectoryByAddress, type DirectoryCommunity, useDirectories } from './use-directories'; import { findDirectoryByAddress, type DirectoryCommunity, useDirectories } from './use-directories';
import { getDirectoryCandidateBoardByAddress } from '../lib/utils/directory-list-lookup-utils'; import { getDirectoryCandidateBoardByAddress } from '../lib/utils/directory-list-lookup-utils';
import { getSpecialBoardByAddress } from '../lib/special-boards';
const isLikelyCommunityName = (value: string) => value.includes('.'); const isLikelyCommunityName = (value: string) => value.includes('.');
@@ -10,6 +11,18 @@ const getCommunityIdentifier = (communityAddress: string | undefined, directorie
return undefined; return undefined;
} }
const specialBoard = getSpecialBoardByAddress(communityAddress);
if (specialBoard) {
return specialBoard.publicKey
? {
name: specialBoard.address,
publicKey: specialBoard.publicKey,
}
: {
name: specialBoard.address,
};
}
const directory = findDirectoryByAddress(directories, communityAddress); const directory = findDirectoryByAddress(directories, communityAddress);
const directoryCandidate = getDirectoryCandidateBoardByAddress(communityAddress); const directoryCandidate = getDirectoryCandidateBoardByAddress(communityAddress);
const name = directory?.name ?? directory?.address ?? directoryCandidate?.address; const name = directory?.name ?? directory?.address ?? directoryCandidate?.address;