feat(flash board): add SWF posting support (#1145)

This commit is contained in:
Tommaso Casaburi
2026-05-30 16:07:41 +07:00
committed by GitHub
parent 56894700c1
commit 9b3a95dd95
69 changed files with 1372 additions and 63 deletions
+56 -1
View File
@@ -25,6 +25,7 @@ import { hasModQueueAccessRole } from '../../lib/utils/mod-access';
import { getBoardPath } from '../../lib/utils/route-utils';
import { isAllView, isCatalogView, isModQueueView, isModView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
import { getCommentFlagOptionsForDirectory, getCommentFlagPublishOptionsForDirectory, type CommentFlagSelectOption } from '../../lib/comment-flag-selection';
import { FLASH_TAG_OPTIONS, getFlashTagPublishOptionsForDirectoryCode, isFlashDirectoryCode, type FlashTagOption } from '../../lib/flash-tags';
import { useAccountCommunityAddresses } from '../../hooks/use-account-community-addresses';
import { useDirectories, useDirectoryByAddress } from '../../hooks/use-directories';
import { useCommunityField } from '../../hooks/use-stable-community';
@@ -51,6 +52,11 @@ import debounce from 'lodash/debounce';
const FILE_LINK_PLACEHOLDER = 'https://website.com/image.jpg';
const POST_FORM_FILE_DISPLAY_MAX_LENGTH = 28;
const mergeFlairs = (...flairGroups: Array<Comment['flairs'] | undefined>): Comment['flairs'] | undefined => {
const flairs = flairGroups.flatMap((group) => (Array.isArray(group) ? group : []));
return flairs.length > 0 ? flairs : undefined;
};
const getPostFormFileDisplayLabel = (url: string, uploadedFileName: string | null | undefined, noFileLabel: string): string => {
const raw = getPublishURLFilename(url) || uploadedFileName;
if (!raw) return noFileLabel;
@@ -130,6 +136,7 @@ interface PostFormFieldsProps {
subjectRef: React.Ref<HTMLInputElement>;
optionsRef: React.RefObject<HTMLInputElement>;
flagRef: React.RefObject<HTMLSelectElement>;
flashTagRef: React.RefObject<HTMLSelectElement>;
textRef: React.RefObject<HTMLTextAreaElement>;
urlRef: React.Ref<HTMLInputElement>;
url: string;
@@ -156,6 +163,9 @@ interface PostFormFieldsProps {
rulesPath: string;
requirePostLinkIsMedia: boolean;
flagOptions: CommentFlagSelectOption[];
flashTagOptions: FlashTagOption[];
showFlashTagSelector: boolean;
showFlashUploadPrompt: boolean;
showBbcodeToolbar: boolean;
onBbcodePreviewToggle: () => void;
onPublishReply: () => void;
@@ -177,6 +187,7 @@ const PostFormFields = ({
subjectRef,
optionsRef,
flagRef,
flashTagRef,
textRef,
urlRef,
url,
@@ -203,6 +214,9 @@ const PostFormFields = ({
rulesPath,
requirePostLinkIsMedia,
flagOptions,
flashTagOptions,
showFlashTagSelector,
showFlashUploadPrompt,
showBbcodeToolbar,
onBbcodePreviewToggle,
onPublishReply,
@@ -373,6 +387,21 @@ const PostFormFields = ({
</td>
</tr>
)}
{showFlashTagSelector && (
<tr>
<td>{t('tag')}</td>
<td>
<select name='flashTag' aria-label={t('tag')} ref={flashTagRef} defaultValue=''>
<option value=''>{t('choose_one')}</option>
{flashTagOptions.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</td>
</tr>
)}
{showOekakiControls && (
<tr>
<td>Draw</td>
@@ -440,6 +469,16 @@ const PostFormFields = ({
}}
/>
</li>
{showFlashUploadPrompt && (
<li>
<Trans
i18nKey='post_form_flash_upload_prompt'
components={{
catbox: <a href='https://catbox.moe/' target='_blank' rel='noopener noreferrer' aria-label='Catbox' />,
}}
/>
</li>
)}
{showOekakiControls && isWebRuntime() ? <li>{OEKAKI_WEB_WARNING_TEXT}</li> : null}
</ul>
</td>
@@ -467,6 +506,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
const subjectRef = useRef<HTMLInputElement>(null);
const optionsRef = useRef<HTMLInputElement>(null);
const flagRef = useRef<HTMLSelectElement>(null);
const flashTagRef = useRef<HTMLSelectElement>(null);
const fortuneEntryRef = useRef<FortuneEntry | null>(null);
const diceRollRef = useRef<DiceRoll | null>(null);
const nonokoRedirectPathRef = useRef<string | null>(null);
@@ -488,6 +528,8 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
const requirePostLinkIsMediaFeature = directoryEntry?.features?.requirePostLinkIsMedia;
const requirePostLinkIsMedia = requirePostLinkIsMediaFeature === true || (requirePostLinkIsMediaFeature === undefined && (isInAllView || isInSubscriptionsView));
const flagOptions = getCommentFlagOptionsForDirectory(directoryEntry);
const showFlashUploadPrompt = isFlashDirectoryCode(postOptionsDirectoryCode);
const showFlashTagSelector = showFlashUploadPrompt && !isInPostView;
const accountCommunityAddresses = useAccountCommunityAddresses();
const accountAddress = account?.author?.address;
@@ -536,6 +578,9 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
if (flagRef.current) {
flagRef.current.value = flagRef.current.options[0]?.value ?? '';
}
if (flashTagRef.current) {
flashTagRef.current.value = '';
}
checkContentLength.cancel();
checkPostOptions.cancel();
fortuneEntryRef.current = null;
@@ -597,9 +642,15 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
}
const flagPublishOptions = getCommentFlagPublishOptionsForDirectory(directoryEntry, flagRef.current?.value);
const flashTagPublishOptions = getFlashTagPublishOptionsForDirectoryCode(postOptionsDirectoryCode, flashTagRef.current?.value);
const flairs = mergeFlairs(flagPublishOptions.flairs, flashTagPublishOptions.flairs);
const publishOptions = {
...flagPublishOptions,
...(flairs ? { flairs } : {}),
};
nonokoRedirectPathRef.current = hasNonokoOption(currentOptions) ? getBoardIndexPath() : null;
publishPost({ content: publishContent, ...flagPublishOptions });
publishPost({ content: publishContent, ...publishOptions });
};
// redirect to pending page when pending comment is created
@@ -785,6 +836,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
subjectRef={subjectRef}
optionsRef={optionsRef}
flagRef={flagRef}
flashTagRef={flashTagRef}
textRef={textRef}
urlRef={urlRef}
url={url}
@@ -811,6 +863,9 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
rulesPath={rulesPath}
requirePostLinkIsMedia={requirePostLinkIsMedia}
flagOptions={flagOptions}
flashTagOptions={FLASH_TAG_OPTIONS}
showFlashTagSelector={showFlashTagSelector}
showFlashUploadPrompt={showFlashUploadPrompt}
showBbcodeToolbar={showBbcodeToolbar}
onBbcodePreviewToggle={handleBbcodePreviewToggle}
onPublishReply={onPublishReply}