diff --git a/package.json b/package.json index 7398e447..4b040a05 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "license": "GPL-2.0-only", "private": true, "dependencies": { - "@bitsocialnet/bitsocial-react-hooks": "https://github.com/bitsocialnet/bitsocial-react-hooks.git#0f8c9061cd08a0725a7b9fbd85b922d65e44d677", + "@bitsocialnet/bitsocial-react-hooks": "https://github.com/bitsocialnet/bitsocial-react-hooks.git#0e1d9ccd9c158cd0f161a62471cbf91d4928d317", "@capacitor/app": "7.0.1", "@capacitor/status-bar": "7.0.1", "@capawesome/capacitor-android-edge-to-edge-support": "7.2.2", diff --git a/src/__tests__/app.test.tsx b/src/__tests__/app.test.tsx index 24345f5f..546c73f4 100644 --- a/src/__tests__/app.test.tsx +++ b/src/__tests__/app.test.tsx @@ -50,6 +50,10 @@ const testState = vi.hoisted(() => ({ vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({ useAccount: () => testState.account, useAccountComment: ({ commentIndex }: { commentIndex?: number }) => (typeof commentIndex === 'number' ? testState.accountComments[commentIndex] : undefined), + useCommunity: ({ communityAddress }: { communityAddress?: string }) => (communityAddress ? testState.subplebbits[communityAddress] : undefined), + useAccountCommunities: () => ({ + accountCommunities: Object.fromEntries(testState.accountSubplebbitAddresses.map((address) => [address, { address }])), + }), useSubplebbit: ({ subplebbitAddress }: { subplebbitAddress?: string }) => (subplebbitAddress ? testState.subplebbits[subplebbitAddress] : undefined), })); diff --git a/src/app.tsx b/src/app.tsx index 70403a67..3e2de54b 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,6 +1,6 @@ import { lazy, Suspense, useEffect } from 'react'; import { Navigate, Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom'; -import { useAccount, useAccountComment, useSubplebbit } from '@bitsocialnet/bitsocial-react-hooks'; +import { useAccount, useAccountComment, useCommunity } from '@bitsocialnet/bitsocial-react-hooks'; import { initSnow, removeSnow } from './lib/snow'; import { isAllView, isCatalogView, isModView, isSubscriptionsView } from './lib/utils/view-utils'; import { preloadReplyModal, preloadThemeAssets } from './lib/utils/preload-utils'; @@ -8,10 +8,10 @@ import useReplyModalStore from './stores/use-reply-modal-store'; import useCreateBoardModalStore from './stores/use-create-board-modal-store'; import useSpecialThemeStore from './stores/use-special-theme-store'; import useIsMobile from './hooks/use-is-mobile'; -import { useAccountSubplebbitAddresses } from './hooks/use-account-subplebbit-addresses'; +import { useAccountCommunityAddresses } from './hooks/use-account-community-addresses'; import useTheme from './hooks/use-theme'; import { useDirectories } from './hooks/use-directories'; -import { useResolvedSubplebbitAddress } from './hooks/use-resolved-subplebbit-address'; +import { useResolvedCommunityAddress } from './hooks/use-resolved-community-address'; import { getBoardPath, getSubplebbitAddress, @@ -69,8 +69,9 @@ const BoardLayout = () => { const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const isInModView = isModView(location.pathname); const directories = useDirectories(); - const subplebbitAddress = boardIdentifier ? getSubplebbitAddress(boardIdentifier, directories) : undefined; + const communityAddress = boardIdentifier ? getSubplebbitAddress(boardIdentifier, directories) : undefined; const pendingPost = useAccountComment({ commentIndex: accountCommentIndex ? parseInt(accountCommentIndex) : undefined }); + const pendingPostCommunityAddress = pendingPost?.communityAddress || pendingPost?.subplebbitAddress; const { closeCreateBoardModal } = useCreateBoardModalStore(); const isOnPostRoute = isPostRoute(location.pathname); const isOnPendingPostRoute = isPendingPostRoute(location.pathname); @@ -96,8 +97,8 @@ const BoardLayout = () => { // force rerender of post form when navigating between pages, except when opening settings modal in current view const key = location.pathname.endsWith('/settings') - ? `${subplebbitAddress}-${location.pathname.replace(/\/settings$/, '')}` - : `${subplebbitAddress}-${location.pathname}`; + ? `${communityAddress}-${location.pathname.replace(/\/settings$/, '')}` + : `${communityAddress}-${location.pathname}`; if (pageNumber === '1') { return ; @@ -143,7 +144,7 @@ const BoardLayout = () => { {isMobile - ? (subplebbitAddress || isInAllView || isInModView || isInSubscriptionsView || pendingPost?.subplebbitAddress || isOnModQueueRoute) && + ? (communityAddress || isInAllView || isInModView || isInSubscriptionsView || pendingPostCommunityAddress || isOnModQueueRoute) && (isInCatalogView ? ( <> @@ -156,7 +157,7 @@ const BoardLayout = () => { {isInAllView && } )) - : (subplebbitAddress || isInAllView || isInModView || isInSubscriptionsView || pendingPost?.subplebbitAddress || isOnModQueueRoute) && ( + : (communityAddress || isInAllView || isInModView || isInSubscriptionsView || pendingPostCommunityAddress || isOnModQueueRoute) && ( <> {!(isInAllView || isInSubscriptionsView || isInModView) && !isOnModQueueRoute && } @@ -172,7 +173,7 @@ const BoardLayout = () => { const GlobalLayout = () => { useTheme(); - const { activeCid, parentNumber, threadNumber, threadCid, subplebbitAddress, closeModal, showReplyModal, scrollY } = useReplyModalStore(); + const { activeCid, parentNumber, threadNumber, threadCid, subplebbitAddress: activeCommunityAddress, closeModal, showReplyModal, scrollY } = useReplyModalStore(); const location = useLocation(); const isInSettingsView = location.pathname.endsWith('/settings'); @@ -183,7 +184,7 @@ const GlobalLayout = () => { - {activeCid && threadCid && subplebbitAddress && ( + {activeCid && threadCid && activeCommunityAddress && ( { postCid={threadCid} scrollY={scrollY} showReplyModal={showReplyModal} - subplebbitAddress={subplebbitAddress} + communityAddress={activeCommunityAddress} /> )} @@ -239,9 +240,9 @@ const ModQueueRoute = () => { const { boardIdentifier } = useParams(); const account = useAccount(); const accountAddress = account?.author?.address; - const subplebbitAddress = useResolvedSubplebbitAddress(); - const subplebbit = useSubplebbit({ subplebbitAddress }); - const accountSubplebbitAddresses = useAccountSubplebbitAddresses(); + const communityAddress = useResolvedCommunityAddress(); + const community = useCommunity({ communityAddress }); + const accountCommunityAddresses = useAccountCommunityAddresses(); if (!account) { return null; @@ -252,17 +253,17 @@ const ModQueueRoute = () => { } if (!boardIdentifier) { - return accountSubplebbitAddresses.length > 0 ? : ; + return accountCommunityAddresses.length > 0 ? : ; } // Wait for board role metadata before enforcing access to avoid false redirects during initial load. - const boardState = subplebbit?.state; - const isBoardLoading = !subplebbit || !boardState || (boardState !== 'succeeded' && boardState !== 'failed'); + const boardState = community?.state; + const isBoardLoading = !community || !boardState || (boardState !== 'succeeded' && boardState !== 'failed'); if (isBoardLoading) { return null; } - const accountRole = subplebbit?.roles?.[accountAddress]?.role; + const accountRole = community?.roles?.[accountAddress]?.role; return hasModQueueAccessRole(accountRole) ? : ; }; diff --git a/src/components/__tests__/post-community-address-compat.test.tsx b/src/components/__tests__/post-community-address-compat.test.tsx new file mode 100644 index 00000000..fde22b74 --- /dev/null +++ b/src/components/__tests__/post-community-address-compat.test.tsx @@ -0,0 +1,445 @@ +import * as React from 'react'; +import { createElement } from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { MemoryRouter } from 'react-router-dom'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import PostDesktop from '../post-desktop'; +import PostMobile from '../post-mobile'; + +(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true; +const act = (React as { act?: (cb: () => void | Promise) => void | Promise }).act as (cb: () => void | Promise) => void | Promise; + +type TestComment = { + author?: { + address?: string; + shortAddress?: string; + }; + cid?: string; + communityAddress?: string; + content?: string; + deleted?: boolean; + index?: number; + link?: string; + linkHeight?: number; + linkWidth?: number; + number?: number; + parentCid?: string; + pinned?: boolean; + postCid?: string; + removed?: boolean; + replyCount?: number; + replies?: { + pages?: Record< + string, + { + comments?: TestComment[]; + } + >; + }; + state?: string; + subplebbitAddress?: string; + thumbnailUrl?: string; + timestamp?: number; + updatedAt?: number; +}; + +const testState = vi.hoisted(() => ({ + addChallengeMock: vi.fn(), + openReplyModalMock: vi.fn(), + replyComments: [] as Array, + setResetFunctionMock: vi.fn(), +})); + +const getMockPreloadedReplies = (comment?: TestComment, sortType?: string) => { + if (!comment) { + return []; + } + + const preloadedReplies = + comment.replies?.pages?.[sortType || 'best']?.comments ?? Object.values(comment.replies?.pages ?? {}).find((page) => page?.comments?.length)?.comments ?? []; + + const compatibleReplies: TestComment[] = []; + for (const reply of preloadedReplies) { + if (!reply?.communityAddress || reply.communityAddress !== comment.communityAddress) { + break; + } + compatibleReplies.push(reply); + } + + return compatibleReplies; +}; + +vi.mock('react-i18next', () => ({ + Trans: ({ i18nKey, values }: { i18nKey?: string; values?: Record }) => + createElement('span', {}, `${i18nKey ?? 'trans'}:${JSON.stringify(values ?? {})}`), + useTranslation: () => ({ + t: (key: string) => key, + }), +})); + +vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({ + useAccount: () => ({ author: { address: '0xviewer' } }), + useAccountComment: () => undefined, + useEditedComment: () => ({ editedComment: undefined }), + usePublishCommentModeration: () => ({ + error: undefined, + publishCommentModeration: vi.fn(), + state: 'initializing', + }), + useReplies: ({ comment, sortType }: { comment?: TestComment; sortType?: string }) => { + testState.replyComments.push(comment); + return { + hasMore: false, + loadMore: vi.fn(), + replies: getMockPreloadedReplies(comment, sortType), + }; + }, +})); + +vi.mock('react-virtuoso', () => ({ + Virtuoso: React.forwardRef( + ( + { + components, + data = [], + itemContent, + }: { + components?: { Footer?: React.ComponentType }; + data?: TestComment[]; + itemContent: (index: number, item: TestComment) => React.ReactNode; + }, + ref: React.ForwardedRef<{ getState: (cb: (snapshot: { ranges: number[]; scrollTop: number }) => void) => void }>, + ) => { + React.useImperativeHandle(ref, () => ({ + getState: (cb) => cb({ ranges: [0], scrollTop: 0 }), + })); + + return createElement( + 'div', + { 'data-testid': 'virtuoso' }, + data.map((item, index) => createElement('div', { key: item.cid ?? index }, itemContent(index, item))), + components?.Footer ? createElement(components.Footer) : null, + ); + }, + ), +})); + +vi.mock('../../lib/get-short-address', () => ({ + default: (value?: string) => (value ? value.slice(0, 4) : ''), +})); + +vi.mock('../../views/post/post.module.css', () => ({ + default: new Proxy( + {}, + { + get: (_target, property) => String(property), + }, + ), +})); + +vi.mock('../../lib/utils/media-utils', () => ({ + getDisplayMediaInfoType: (type?: string) => type ?? 'unknown', + getHasThumbnail: () => true, + getMediaDimensions: () => '100x100', +})); + +vi.mock('../../lib/utils/post-utils', () => ({ + getTextColorForBackground: () => '#fff', + hashStringToColor: () => '#000', +})); + +vi.mock('../../lib/utils/time-utils', () => ({ + getFormattedDate: () => '2026-03-13', + getFormattedTimeAgo: () => 'moments ago', +})); + +vi.mock('../../lib/utils/pending-approval-moderation', () => ({ + approvePendingCommentModeration: {}, + isPendingApprovalRejected: () => false, + rejectPendingCommentModeration: {}, +})); + +vi.mock('../../lib/utils/url-utils', () => ({ + isValidURL: () => true, +})); + +vi.mock('../../lib/utils/view-utils', () => ({ + isAllView: (pathname: string) => pathname === '/all', + isModQueueView: () => false, + isModView: () => false, + isPendingPostView: () => false, + isPostPageView: (pathname: string) => pathname.includes('/thread/'), + isSubscriptionsView: () => false, +})); + +vi.mock('../../stores/use-mod-queue-store', () => ({ + default: (selector?: (state: { getAlertThresholdSeconds: () => number }) => unknown) => { + const state = { + getAlertThresholdSeconds: () => 0, + }; + + return selector ? selector(state) : state; + }, +})); + +vi.mock('../../hooks/use-directories', () => ({ + findDirectoryByAddress: (_directories: unknown[], address?: string) => (address ? { address, features: {} } : undefined), + useDirectories: () => [{ address: 'music-posting.eth', title: '/mu/ - Music' }], +})); + +vi.mock('../../lib/utils/route-utils', () => ({ + getBoardPath: (address?: string) => (address ? 'mu' : undefined), +})); + +vi.mock('../../hooks/use-author-address-click', () => ({ + default: () => vi.fn(), +})); + +vi.mock('../../hooks/use-comment-media-info', () => ({ + useCommentMediaInfo: (link?: string) => (link ? { type: 'image', url: link } : undefined), +})); + +vi.mock('../../hooks/use-count-links-in-replies', () => ({ + default: () => 0, +})); + +vi.mock('../../hooks/use-fetch-gif-first-frame', () => ({ + default: () => ({ + status: 'idle', + }), +})); + +vi.mock('../../hooks/use-hide', () => ({ + default: () => ({ + hidden: false, + hide: vi.fn(), + unhide: vi.fn(), + }), +})); + +vi.mock('../../hooks/use-state-string', () => ({ + default: () => undefined, +})); + +vi.mock('../../hooks/use-scroll-to-reply', () => ({ + default: () => undefined, +})); + +vi.mock('../../hooks/use-current-time', () => ({ + useCurrentTime: () => 1_710_000_000, +})); + +vi.mock('../../hooks/use-board-pseudonymity-mode', () => ({ + useBoardPseudonymityMode: () => 'none', +})); + +vi.mock('../comment-content', () => ({ + default: ({ comment }: { comment?: TestComment }) => createElement('div', { 'data-testid': 'comment-content' }, comment?.cid ?? 'missing'), +})); + +vi.mock('../comment-media', () => ({ + default: () => createElement('div', { 'data-testid': 'comment-media' }, 'media'), +})); + +vi.mock('../edit-menu/edit-menu', () => ({ + default: () => createElement('div', { 'data-testid': 'edit-menu' }, 'edit'), +})); + +vi.mock('../failed-publish-notice', () => ({ + default: () => createElement('div', { 'data-testid': 'failed-publish-notice' }, 'failed-publish-notice'), +})); + +vi.mock('../embed', () => ({ + canEmbed: () => false, +})); + +vi.mock('../loading-ellipsis', () => ({ + default: ({ string }: { string: string }) => createElement('div', { 'data-testid': 'loading-ellipsis' }, string), +})); + +vi.mock('../post-desktop/post-menu-desktop', () => ({ + default: ({ postMenu }: { postMenu: { communityAddress?: string } }) => + createElement('div', { 'data-testid': 'post-menu-desktop' }, postMenu.communityAddress ?? 'missing'), +})); + +vi.mock('../reply-quote-preview', () => ({ + default: ({ backlinkReply }: { backlinkReply?: TestComment }) => createElement('div', { 'data-testid': 'reply-quote-preview' }, backlinkReply?.cid ?? 'missing'), +})); + +vi.mock('../tooltip', () => ({ + default: ({ children }: { children?: React.ReactNode }) => createElement(React.Fragment, {}, children), +})); + +vi.mock('../../lib/snow', () => ({ + shouldShowSnow: () => false, +})); + +vi.mock('../../stores/use-reply-modal-store', () => ({ + default: () => ({ + openReplyModal: testState.openReplyModalMock, + }), +})); + +vi.mock('../../stores/use-challenges-store', () => ({ + default: { + getState: () => ({ + addChallenge: testState.addChallengeMock, + }), + }, +})); + +vi.mock('../../stores/use-feed-reset-store', () => ({ + default: (selector: (state: { setResetFunction: typeof testState.setResetFunctionMock }) => unknown) => + selector({ + setResetFunction: testState.setResetFunctionMock, + }), +})); + +vi.mock('../../hooks/use-register-fresh-replies', () => ({ + default: () => undefined, +})); + +vi.mock('../../lib/utils/challenge-utils', () => ({ + alertChallengeVerificationFailed: vi.fn(), +})); + +vi.mock('../../hooks/use-quoted-by-map', () => ({ + default: () => new Map(), +})); + +vi.mock('../../hooks/use-progressive-render', () => ({ + default: (replies: TestComment[]) => replies, +})); + +vi.mock('../../hooks/use-fresh-replies', () => ({ + default: (replies: TestComment[]) => replies, +})); + +vi.mock('../../lib/constants', () => ({ + BOARD_REPLIES_PREVIEW_FETCH_SIZE: 5, + BOARD_REPLIES_PREVIEW_VISIBLE_COUNT: 3, + REPLIES_PER_PAGE: 20, +})); + +vi.mock('../../lib/utils/replies-preview-utils', () => ({ + computeOmittedCount: () => 0, + filterRepliesForDisplay: (replies: TestComment[]) => replies, + getPreviewDisplayReplies: (replies: TestComment[]) => replies, + getTotalReplyCount: ({ replyCount }: { replyCount?: number }) => replyCount ?? 0, +})); + +vi.mock('../../lib/utils/thread-scroll-utils', () => ({ + getThreadTopNavigationState: () => undefined, + scrollThreadContainerToTop: () => true, +})); + +vi.mock('../../hooks/use-delete-failed-post', () => ({ + default: () => ({ + canDeleteFailedPost: false, + isDeletingFailedPost: false, + onDeleteFailedPost: vi.fn(), + }), +})); + +vi.mock('../post-mobile/post-menu-mobile', () => ({ + default: ({ postMenu }: { postMenu: { communityAddress?: string } }) => + createElement('div', { 'data-testid': 'post-menu-mobile' }, postMenu.communityAddress ?? 'missing'), +})); + +vi.mock('../../lib/utils/reply-backlink-utils', () => ({ + getRenderableMobileBacklinks: () => ({ + directReplyBacklinks: [], + opBacklinks: [], + quotedReplyBacklinks: [], + }), +})); + +let container: HTMLDivElement; +let root: Root; + +const flushEffects = async (count = 3) => { + for (let i = 0; i < count; i += 1) { + await act(async () => { + await Promise.resolve(); + await new Promise((resolve) => setTimeout(resolve, 0)); + }); + } +}; + +const renderWithRoute = async (element: React.ReactNode, initialEntry = '/all') => { + await act(async () => { + root.render(createElement(MemoryRouter, { initialEntries: [initialEntry] }, element)); + }); + await flushEffects(); +}; + +const makeLegacyThread = (): TestComment => ({ + author: { address: '0xauthor', shortAddress: 'anon' }, + cid: 'post-1', + content: 'Original post', + link: 'https://example.com/file.png', + linkHeight: 100, + linkWidth: 100, + number: 1, + postCid: 'post-1', + replyCount: 1, + replies: { + pages: { + new: { + comments: [ + { + author: { address: '0xreply', shortAddress: 'reply' }, + cid: 'reply-1', + content: 'Reply', + number: 2, + parentCid: 'post-1', + postCid: 'post-1', + subplebbitAddress: 'music-posting.eth', + }, + ], + }, + }, + }, + subplebbitAddress: 'music-posting.eth', + timestamp: 1_710_000_000, +}); + +describe('post community address compatibility', () => { + beforeEach(() => { + vi.clearAllMocks(); + testState.replyComments = []; + + container = document.createElement('div'); + document.body.appendChild(container); + root = createRoot(container); + }); + + afterEach(() => { + act(() => root.unmount()); + container.remove(); + }); + + it('renders desktop multiboard posts with only subplebbitAddress and still fetches replies', async () => { + await renderWithRoute(createElement(PostDesktop, { post: makeLegacyThread() })); + + const primaryRepliesComment = testState.replyComments.find((comment) => comment?.cid === 'post-1'); + expect(primaryRepliesComment?.communityAddress).toBe('music-posting.eth'); + expect(primaryRepliesComment?.replies?.pages?.new?.comments?.[0]?.communityAddress).toBe('music-posting.eth'); + expect(container.querySelector('[data-testid="post-menu-desktop"]')?.textContent).toBe('music-posting.eth'); + expect(document.body.querySelector('a[href="/mu"]')?.textContent).toContain('mu'); + expect(container.querySelector('[data-testid="comment-media"]')).toBeTruthy(); + expect(container.textContent).toContain('reply-1'); + }); + + it('renders mobile multiboard posts with only subplebbitAddress and still fetches replies', async () => { + await renderWithRoute(createElement(PostMobile, { post: makeLegacyThread() })); + + const primaryRepliesComment = testState.replyComments.find((comment) => comment?.cid === 'post-1'); + expect(primaryRepliesComment?.communityAddress).toBe('music-posting.eth'); + expect(primaryRepliesComment?.replies?.pages?.new?.comments?.[0]?.communityAddress).toBe('music-posting.eth'); + expect(container.querySelector('[data-testid="post-menu-mobile"]')?.textContent).toBe('music-posting.eth'); + expect(document.body.querySelector('a[href="/mu"]')?.textContent).toContain('Board: mu'); + expect(container.querySelector('[data-testid="comment-media"]')).toBeTruthy(); + expect(container.textContent).toContain('reply-1'); + }); +}); diff --git a/src/components/blotter-message/__tests__/blotter-message.test.tsx b/src/components/blotter-message/__tests__/blotter-message.test.tsx new file mode 100644 index 00000000..6a0d41a3 --- /dev/null +++ b/src/components/blotter-message/__tests__/blotter-message.test.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; +import { createElement } from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import BlotterMessage from '../blotter-message'; + +(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true; +const act = (React as { act?: (cb: () => void | Promise) => void | Promise }).act as (cb: () => void | Promise) => void | Promise; + +vi.mock('../blotter-message.module.css', () => ({ + default: { + versionLink: 'versionLink', + }, +})); + +let container: HTMLDivElement; +let root: Root; + +describe('BlotterMessage', () => { + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + root = createRoot(container); + }); + + afterEach(() => { + act(() => root.unmount()); + container.remove(); + }); + + it('normalizes legacy subplebbit wording without rewriting plain community text', async () => { + await act(async () => { + root.render( + createElement(BlotterMessage, { + entry: { + id: 'manual-1', + kind: 'manual', + message: 'Moved a subplebbit into a community spotlight', + timestamp: 1_710_000_000, + }, + }), + ); + }); + + expect(container.textContent).toContain('Moved a board into a community spotlight'); + expect(container.textContent).not.toContain('subplebbit'); + expect(container.textContent).not.toContain('board spotlight'); + }); + + it('normalizes release one-liners after the version prefix', async () => { + await act(async () => { + root.render( + createElement(BlotterMessage, { + entry: { + id: 'release-1', + kind: 'release', + message: 'v0.7.0: Fix subplebbit loading in plebchan', + timestamp: 1_710_000_000, + version: '0.7.0', + }, + }), + ); + }); + + expect(container.querySelector('a')?.getAttribute('href')).toBe('https://github.com/bitsocialnet/5chan/releases/tag/v0.7.0'); + expect(container.textContent).toContain('Fix board loading in 5chan'); + }); +}); diff --git a/src/components/board-buttons/__tests__/board-buttons.test.tsx b/src/components/board-buttons/__tests__/board-buttons.test.tsx index 4c977206..e7e7b2e7 100644 --- a/src/components/board-buttons/__tests__/board-buttons.test.tsx +++ b/src/components/board-buttons/__tests__/board-buttons.test.tsx @@ -15,7 +15,7 @@ type DirectoryEntry = { }; const testState = vi.hoisted(() => ({ - accountComment: undefined as { subplebbitAddress?: string } | undefined, + accountComment: undefined as { communityAddress?: string } | undefined, alertThresholdUnit: 'minutes' as 'hours' | 'minutes', alertThresholdValue: 5, commentsByCid: {} as Record, @@ -32,7 +32,7 @@ const testState = vi.hoisted(() => ({ navigateMock: vi.fn(), pageNumber: 7 as number | null, resetMock: vi.fn(), - resolvedSubplebbitAddress: 'music-posting.eth' as string | undefined, + resolvedCommunityAddress: 'music-posting.eth' as string | undefined, searchText: '', setAlertThresholdMock: vi.fn(), setFilterMock: vi.fn(), @@ -89,8 +89,8 @@ vi.mock('../../../hooks/use-directories', () => ({ useDirectoryByAddress: (address: string | undefined) => testState.directories.find((entry) => entry.address === address), })); -vi.mock('../../../hooks/use-resolved-subplebbit-address', () => ({ - useResolvedSubplebbitAddress: () => testState.resolvedSubplebbitAddress, +vi.mock('../../../hooks/use-resolved-community-address', () => ({ + useResolvedCommunityAddress: () => testState.resolvedCommunityAddress, })); vi.mock('../../../stores/use-catalog-filters-store', () => ({ @@ -230,7 +230,7 @@ describe('BoardButtons', () => { testState.isMobile = true; testState.linkCount = 3; testState.pageNumber = 7; - testState.resolvedSubplebbitAddress = 'music-posting.eth'; + testState.resolvedCommunityAddress = 'music-posting.eth'; testState.searchText = ''; testState.showOPComment = false; testState.sortType = 'active'; diff --git a/src/components/board-buttons/board-buttons.tsx b/src/components/board-buttons/board-buttons.tsx index 1cb104ea..96b85ae1 100644 --- a/src/components/board-buttons/board-buttons.tsx +++ b/src/components/board-buttons/board-buttons.tsx @@ -5,7 +5,7 @@ import { isAllView, isCatalogView, isModView, isModQueueView, isPendingPostView, import { usePostPageNumber } from '../../hooks/use-post-page-number'; import { useDirectories, useDirectoryByAddress } from '../../hooks/use-directories'; import { getBoardPath, isDirectoryBoard } from '../../lib/utils/route-utils'; -import { useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address'; +import { useResolvedCommunityAddress } from '../../hooks/use-resolved-community-address'; import useCatalogFiltersStore from '../../stores/use-catalog-filters-store'; import useCatalogStyleStore from '../../stores/use-catalog-style-store'; import useFeedResetStore from '../../stores/use-feed-reset-store'; @@ -73,7 +73,7 @@ export const ArchiveButton = ({ address, isInAllView, isInSubscriptionsView, isI const SubscribeButton = ({ address }: BoardButtonsProps) => { const { t } = useTranslation(); - const { subscribed, subscribe, unsubscribe } = useSubscribe({ subplebbitAddress: address }); + const { subscribed, subscribe, unsubscribe } = useSubscribe({ communityAddress: address }); return (