mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(post-form): convert twimg query-format links in the reply modal (#1168)
Share getPublishLinkOptions between the inline post form and the reply modal so the modal publishes twimg ?format= links in their .jpg/.png form (previously raw), and rewrite the link field on blur in both so the conversion is visible. Also gate the dev service worker's runtime asset cache to production so dev no longer serves stale /src modules.
This commit is contained in:
@@ -678,6 +678,41 @@ describe('ReplyModal', () => {
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('publishes twimg query-format reply links with a path extension', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'reply body';
|
||||
|
||||
await renderReplyModal('/mu/thread/post-1');
|
||||
|
||||
const linkInput = container.querySelectorAll<HTMLInputElement>('input[type="text"]')[2];
|
||||
|
||||
// The publish path normalizes the raw `?format=` link even without blurring the field.
|
||||
await dispatchInput(linkInput, 'https://pbs.twimg.com/media/HKUAehoXUAAXkMb?format=jpg&name=4096x4096');
|
||||
expect(linkInput.value).toBe('https://pbs.twimg.com/media/HKUAehoXUAAXkMb?format=jpg&name=4096x4096');
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledWith(expect.objectContaining({ link: 'https://pbs.twimg.com/media/HKUAehoXUAAXkMb.jpg' }));
|
||||
});
|
||||
|
||||
it('rewrites twimg query-format reply links to their path-extension form on blur', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'reply body';
|
||||
|
||||
await renderReplyModal('/mu/thread/post-1');
|
||||
|
||||
const linkInput = container.querySelectorAll<HTMLInputElement>('input[type="text"]')[2];
|
||||
|
||||
await dispatchInput(linkInput, 'https://pbs.twimg.com/media/HKUAehoXUAAXkMb?format=jpg&name=4096x4096');
|
||||
expect(linkInput.value).toBe('https://pbs.twimg.com/media/HKUAehoXUAAXkMb?format=jpg&name=4096x4096');
|
||||
|
||||
await act(async () => {
|
||||
linkInput.dispatchEvent(new FocusEvent('focusout', { bubbles: true }));
|
||||
});
|
||||
|
||||
expect(linkInput.value).toBe('https://pbs.twimg.com/media/HKUAehoXUAAXkMb.jpg');
|
||||
});
|
||||
|
||||
it('moves YouTube links into reply content and publishes the thumbnail link on media-only boards', async () => {
|
||||
const youtubeLink = 'https://youtu.be/reply123';
|
||||
const thumbnailLink = 'https://img.youtube.com/vi/reply123/0.jpg';
|
||||
|
||||
@@ -3,7 +3,8 @@ import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { setAccount, useAccount } from '@bitsocial/bitsocial-react-hooks';
|
||||
import { getExpiringMediaLinkAlert, getPublishFileDisplayName } from '../../lib/utils/media-link-validation-utils';
|
||||
import { getExpiringMediaLinkAlert, getPublishFileDisplayName, getPublishLinkOptions } from '../../lib/utils/media-link-validation-utils';
|
||||
import { getTwimgMediaFilePublishUrl } from '../../lib/utils/media-utils';
|
||||
import { getCommentFlagOptionsForDirectory, getCommentFlagPublishOptionsForDirectory } from '../../lib/comment-flag-selection';
|
||||
import {
|
||||
type DiceRoll,
|
||||
@@ -185,7 +186,7 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
|
||||
|
||||
setError(null);
|
||||
nonokoRedirectPathRef.current = hasNonokoOption(currentOptions) ? `/${postOptionsDirectoryCode || params.boardIdentifier || communityAddress}` : null;
|
||||
publishReply({ content: publishContent, ...(appliedYouTubeConversion ? { link: currentUrl } : {}), ...flagPublishOptions });
|
||||
publishReply({ content: publishContent, ...getPublishLinkOptions(currentUrl, appliedYouTubeConversion), ...flagPublishOptions });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -431,6 +432,19 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
|
||||
}
|
||||
};
|
||||
|
||||
// Mirror the inline post form: normalize twimg `?format=` links to their `.jpg`/`.png` form once
|
||||
// the field loses focus, so the conversion that happens at publish time is visible in the input.
|
||||
const handleLinkBlur = () => {
|
||||
const currentValue = urlRef.current?.value ?? '';
|
||||
const twimgPublishUrl = getTwimgMediaFilePublishUrl(currentValue);
|
||||
if (twimgPublishUrl && twimgPublishUrl !== currentValue) {
|
||||
if (urlRef.current) {
|
||||
urlRef.current.value = twimgPublishUrl;
|
||||
}
|
||||
setLinkValue(twimgPublishUrl);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const canInsertQuote = showReplyModal && quoteInsertRequestId !== 0 && !!textRef.current;
|
||||
|
||||
@@ -601,6 +615,7 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
|
||||
onChange={(e) => {
|
||||
handleLinkChange(e.target.value);
|
||||
}}
|
||||
onBlur={handleLinkBlur}
|
||||
/>
|
||||
</div>
|
||||
{showOekakiControls && (
|
||||
|
||||
Reference in New Issue
Block a user