diff --git a/src/views/mod-queue/__tests__/mod-queue.test.tsx b/src/views/mod-queue/__tests__/mod-queue.test.tsx index 26d0d335..49040d78 100644 --- a/src/views/mod-queue/__tests__/mod-queue.test.tsx +++ b/src/views/mod-queue/__tests__/mod-queue.test.tsx @@ -95,8 +95,18 @@ vi.mock('@bitsocial/bitsocial-react-hooks', () => ({ })); vi.mock('@bitsocial/bitsocial-react-hooks/dist/stores/accounts/index.js', () => ({ - default: (selector: (state: { accountsEditsSummaries: Record>; activeAccountId: string }) => unknown) => - selector({ accountsEditsSummaries: { account: {} }, activeAccountId: 'account' }), + default: ( + selector: (state: { + accounts: Record; + accountsEditsSummaries: Record>; + activeAccountId: string; + }) => unknown, + ) => + selector({ + accounts: { account: testState.account }, + accountsEditsSummaries: { account: {} }, + activeAccountId: 'account', + }), })); vi.mock('@floating-ui/react', () => ({ @@ -150,6 +160,8 @@ vi.mock('../../../stores/use-challenges-store', () => { }); vi.mock('../../../hooks/use-account-community-addresses', () => ({ + areStringArraysEqual: (previous: readonly string[] | undefined, next: readonly string[] | undefined) => + previous === next || (!!previous && !!next && previous.length === next.length && previous.every((value, index) => value === next[index])), useAccountCommunityAddresses: () => testState.accountCommunityAddresses, })); diff --git a/src/views/rules/__tests__/rules.test.tsx b/src/views/rules/__tests__/rules.test.tsx index 9d513b32..b064f81d 100644 --- a/src/views/rules/__tests__/rules.test.tsx +++ b/src/views/rules/__tests__/rules.test.tsx @@ -156,6 +156,23 @@ describe('Rules', () => { expect(scrollIntoViewMock).toHaveBeenCalled(); }); + it('re-scrolls an active directory hash when directory data refreshes', async () => { + await renderRules('/rules#b'); + expect(scrollIntoViewMock).toHaveBeenCalledTimes(1); + + testState.directories = [{ address: 'animals-posting.eth', title: '/an/ - Animals & Nature', directoryCode: 'an' }, ...testState.directories]; + testState.directoryDefaults = { + directories: { + ...testState.directoryDefaults.directories, + an: { directoryCode: 'an', title: '/an/ - Animals & Nature', rules: ['Keep animal posts on topic.'] }, + }, + }; + + await renderRules('/rules#b'); + + expect(scrollIntoViewMock).toHaveBeenCalledTimes(2); + }); + it('ignores address hashes instead of resolving them to directory rules or P2P rules', async () => { testState.communities = { 'anime-posting.eth': { diff --git a/src/views/rules/rules.tsx b/src/views/rules/rules.tsx index ccecc0de..0dcaf974 100644 --- a/src/views/rules/rules.tsx +++ b/src/views/rules/rules.tsx @@ -1,4 +1,4 @@ -import { Fragment, useEffect, useRef, useState, FormEvent } from 'react'; +import { Fragment, useEffect, useState, FormEvent } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { useCommunity } from '@bitsocial/bitsocial-react-hooks'; import { Footer, HomeLogo } from '../home/home'; @@ -240,7 +240,6 @@ const Rules = () => { const directories = useDirectories(); const directoryDefaults = useDirectoryDefaults(); const [loadedAddress, setLoadedAddress] = useState(''); - const scrolledForRef = useRef(null); const hashCode = getRulesHashCode(hash); // Order directories alphabetically by directory code (e.g. /3/, /a/, /aco/...), like 4chan, not by title. @@ -257,7 +256,6 @@ const Rules = () => { useEffect(() => { setLoadedAddress(''); - scrolledForRef.current = null; if (!hashCode) { window.scrollTo(0, 0); } @@ -265,13 +263,12 @@ const Rules = () => { // Deep-link: /rules#code insta-scrolls to a known directory's rules once the matching section is rendered. useEffect(() => { - if (!hashCode || scrolledForRef.current === hashCode || !isDirectoryRoute(hashCode, directories)) { + if (!hashCode || !isDirectoryRoute(hashCode, directories)) { return; } const element = document.getElementById(hashCode); if (element) { element.scrollIntoView(); - scrolledForRef.current = hashCode; } }, [hashCode, directories]);