mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(quotes): keep same-thread board previews local
This commit is contained in:
@@ -41,7 +41,7 @@ let latestValue: ReturnType<typeof usePublishPost>;
|
||||
let root: Root;
|
||||
|
||||
const HookHarness = () => {
|
||||
latestValue = usePublishPost({ subplebbitAddress: 'music.eth' });
|
||||
latestValue = usePublishPost({ communityAddress: 'music.eth' });
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -92,7 +92,6 @@ describe('usePublishPost', () => {
|
||||
spoiler: true,
|
||||
title: 'Hello world',
|
||||
});
|
||||
expect('subplebbitAddress' in latestValue.publishPostOptions).toBe(false);
|
||||
expect(typeof latestValue.publishPostOptions.onChallengeVerification).toBe('function');
|
||||
expect(typeof latestValue.publishPostOptions.onError).toBe('function');
|
||||
});
|
||||
|
||||
@@ -41,6 +41,7 @@ vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({
|
||||
|
||||
vi.mock('../../hooks/use-directories', () => ({
|
||||
useDirectories: () => testState.directories,
|
||||
normalizeBoardAddress: (address?: string) => address?.replace(/(\.bso|\.eth)$/u, ''),
|
||||
}));
|
||||
|
||||
vi.mock('../../lib/utils/external-quote-resolver', () => ({
|
||||
@@ -60,7 +61,7 @@ let latestValue: ReturnType<typeof usePublishReply>;
|
||||
let root: Root;
|
||||
|
||||
const HookHarness = () => {
|
||||
latestValue = usePublishReply({ cid: 'parent-cid', subplebbitAddress: 'music.eth' });
|
||||
latestValue = usePublishReply({ cid: 'parent-cid', communityAddress: 'music.eth' });
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -122,14 +123,13 @@ describe('usePublishReply', () => {
|
||||
quotedCids: ['quoted-cid'],
|
||||
spoiler: true,
|
||||
});
|
||||
expect('subplebbitAddress' in (testState.lastPublishOptions || {})).toBe(false);
|
||||
});
|
||||
|
||||
it('resolves same-board external quote references before triggering publish', async () => {
|
||||
testState.resolveExternalQuoteTargetMock.mockResolvedValue({
|
||||
cid: 'external-cid',
|
||||
route: '/music/thread/external-cid',
|
||||
subplebbitAddress: 'music.eth',
|
||||
communityAddress: 'music.eth',
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
|
||||
@@ -72,4 +72,32 @@ describe('useQuotedByMap', () => {
|
||||
|
||||
expect(latestValue.get('op-cid')?.[0]?.number).toBe(42);
|
||||
});
|
||||
|
||||
it('matches same-board quote numbers across .eth and .bso aliases', () => {
|
||||
usePostNumberStore.setState({
|
||||
cidToNumber: { 'op-cid': 1 },
|
||||
numberToCid: { 'music.eth': { 1: 'op-cid' } },
|
||||
});
|
||||
|
||||
testState.replies = [
|
||||
{
|
||||
cid: 'reply-cid',
|
||||
content: 'replying to >>1',
|
||||
number: 42,
|
||||
state: 'succeeded',
|
||||
subplebbitAddress: 'music.bso',
|
||||
},
|
||||
];
|
||||
|
||||
act(() => {
|
||||
root.render(
|
||||
createElement(() => {
|
||||
latestValue = useQuotedByMap(testState.replies as never, 'music.bso');
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
expect(latestValue.get('op-cid')?.[0]?.cid).toBe('reply-cid');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,11 +6,9 @@ import usePublishAuthorDomainGuard, { getPublishAuthorDomainErrorMessage } from
|
||||
|
||||
type UsePublishPostOptions = {
|
||||
communityAddress?: string;
|
||||
/** legacy compatibility */
|
||||
subplebbitAddress?: string;
|
||||
};
|
||||
|
||||
const usePublishPost = ({ communityAddress: requestedCommunityAddress, subplebbitAddress }: UsePublishPostOptions) => {
|
||||
const usePublishPost = ({ communityAddress }: UsePublishPostOptions) => {
|
||||
const { author, title, content, link, spoiler, publishCommentOptions } = usePublishPostStore((state) => ({
|
||||
author: state.author,
|
||||
title: state.title || undefined,
|
||||
@@ -30,8 +28,6 @@ const usePublishPost = ({ communityAddress: requestedCommunityAddress, subplebbi
|
||||
await abandonPublishRef.current?.();
|
||||
}, []);
|
||||
|
||||
const communityAddress = requestedCommunityAddress ?? subplebbitAddress;
|
||||
|
||||
const createBaseOptions = useCallback(() => {
|
||||
const baseOptions: Comment = {
|
||||
communityAddress,
|
||||
@@ -60,12 +56,8 @@ const usePublishPost = ({ communityAddress: requestedCommunityAddress, subplebbi
|
||||
{} as Partial<Comment>,
|
||||
);
|
||||
|
||||
const {
|
||||
communityAddress: nextCommunityAddress,
|
||||
subplebbitAddress: legacyCommunityAddress,
|
||||
...restOptions
|
||||
} = sanitizedOptions as Partial<Comment> & { subplebbitAddress?: string };
|
||||
const resolvedCommunityAddress = nextCommunityAddress ?? legacyCommunityAddress ?? baseOptions.communityAddress;
|
||||
const { communityAddress: nextCommunityAddress, ...restOptions } = sanitizedOptions;
|
||||
const resolvedCommunityAddress = nextCommunityAddress ?? baseOptions.communityAddress;
|
||||
const newOptions = {
|
||||
...baseOptions,
|
||||
...restOptions,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Comment, useAccount, usePublishComment } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import { useDirectories } from './use-directories';
|
||||
import usePublishReplyStore from '../stores/use-publish-reply-store';
|
||||
import usePostNumberStore from '../stores/use-post-number-store';
|
||||
import usePostNumberStore, { getScopedNumberToCidMap } from '../stores/use-post-number-store';
|
||||
import { getQuotedCidsFromContent, mergeQuotedCids } from '../lib/utils/reply-quote-utils';
|
||||
import { extractUnresolvedExternalQuoteReferences, getExternalQuoteStatusMessage } from '../lib/utils/external-quote-utils';
|
||||
import { resolveExternalQuoteTarget } from '../lib/utils/external-quote-resolver';
|
||||
@@ -13,14 +13,10 @@ import usePublishAuthorDomainGuard, { getPublishAuthorDomainErrorMessage } from
|
||||
type UsePublishReplyOptions = {
|
||||
cid: string;
|
||||
communityAddress?: string;
|
||||
/** legacy compatibility */
|
||||
subplebbitAddress?: string;
|
||||
postCid?: string;
|
||||
};
|
||||
|
||||
const usePublishReply = ({ cid, communityAddress: requestedCommunityAddress, subplebbitAddress, postCid }: UsePublishReplyOptions) => {
|
||||
const communityAddress = requestedCommunityAddress ?? subplebbitAddress;
|
||||
|
||||
const usePublishReply = ({ cid, communityAddress, postCid }: UsePublishReplyOptions) => {
|
||||
const { t } = useTranslation();
|
||||
const parentCid = cid;
|
||||
const account = useAccount();
|
||||
@@ -78,12 +74,8 @@ const usePublishReply = ({ cid, communityAddress: requestedCommunityAddress, sub
|
||||
{} as Partial<Comment>,
|
||||
);
|
||||
|
||||
const {
|
||||
communityAddress: nextCommunityAddress,
|
||||
subplebbitAddress: legacyCommunityAddress,
|
||||
...restOptions
|
||||
} = sanitizedOptions as Partial<Comment> & { subplebbitAddress?: string };
|
||||
const resolvedCommunityAddress = nextCommunityAddress ?? legacyCommunityAddress ?? baseOptions.communityAddress;
|
||||
const { communityAddress: nextCommunityAddress, ...restOptions } = sanitizedOptions;
|
||||
const resolvedCommunityAddress = nextCommunityAddress ?? baseOptions.communityAddress;
|
||||
const newOptions = {
|
||||
...baseOptions,
|
||||
...restOptions,
|
||||
@@ -96,7 +88,7 @@ const usePublishReply = ({ cid, communityAddress: requestedCommunityAddress, sub
|
||||
|
||||
const resetPublishReplyOptions = useCallback(() => resetPublishReplyStore(parentCid), [parentCid, resetPublishReplyStore]);
|
||||
|
||||
const scopedNumberToCid = usePostNumberStore((state) => (communityAddress ? state.numberToCid[communityAddress] : undefined));
|
||||
const scopedNumberToCid = usePostNumberStore((state) => getScopedNumberToCidMap(state.numberToCid, communityAddress));
|
||||
const quotedCids = useMemo(() => getQuotedCidsFromContent(content, scopedNumberToCid), [content, scopedNumberToCid]);
|
||||
const unresolvedExternalQuoteReferences = useMemo(
|
||||
() =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { Comment } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import { QUOTE_NUMBER_REGEX } from '../lib/utils/url-utils';
|
||||
import usePostNumberStore from '../stores/use-post-number-store';
|
||||
import usePostNumberStore, { getScopedNumberToCidMap } from '../stores/use-post-number-store';
|
||||
|
||||
interface ReplyQuoteTargets {
|
||||
reply: Comment;
|
||||
@@ -61,27 +61,27 @@ const extractReplyQuoteTargets = (replies: Comment[]) => {
|
||||
};
|
||||
};
|
||||
|
||||
const useQuotedByMap = (replies: Comment[] = [], subplebbitAddress?: string) => {
|
||||
const useQuotedByMap = (replies: Comment[] = [], communityAddress?: string) => {
|
||||
const stableQuotedByMapRef = useRef<Map<string, Comment[]>>(new Map());
|
||||
const { replyQuoteTargets, quotedPostNumbers } = useMemo(() => extractReplyQuoteTargets(replies), [replies]);
|
||||
|
||||
const quotedNumbersSignature = usePostNumberStore(
|
||||
useCallback(
|
||||
(state) => {
|
||||
const scoped = subplebbitAddress ? state.numberToCid[subplebbitAddress] : undefined;
|
||||
const scoped = getScopedNumberToCidMap(state.numberToCid, communityAddress);
|
||||
return quotedPostNumbers.map((postNumber) => `${postNumber}:${scoped?.[postNumber] ?? ''}`).join('|');
|
||||
},
|
||||
[quotedPostNumbers, subplebbitAddress],
|
||||
[quotedPostNumbers, communityAddress],
|
||||
),
|
||||
);
|
||||
|
||||
const quotedNumberToCid = useMemo(() => {
|
||||
if (quotedPostNumbers.length === 0 || !subplebbitAddress) {
|
||||
if (quotedPostNumbers.length === 0 || !communityAddress) {
|
||||
return {} as Record<number, string>;
|
||||
}
|
||||
|
||||
const { numberToCid } = usePostNumberStore.getState();
|
||||
const scoped = numberToCid[subplebbitAddress];
|
||||
const scoped = getScopedNumberToCidMap(numberToCid, communityAddress);
|
||||
if (!scoped) return {} as Record<number, string>;
|
||||
|
||||
const nextQuotedNumberToCid: Record<number, string> = {};
|
||||
@@ -94,7 +94,7 @@ const useQuotedByMap = (replies: Comment[] = [], subplebbitAddress?: string) =>
|
||||
}
|
||||
|
||||
return nextQuotedNumberToCid;
|
||||
}, [quotedPostNumbers, subplebbitAddress, quotedNumbersSignature]);
|
||||
}, [quotedPostNumbers, communityAddress, quotedNumbersSignature]);
|
||||
|
||||
return useMemo(() => {
|
||||
const map = new Map<string, Comment[]>();
|
||||
|
||||
Reference in New Issue
Block a user