mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
Country-only boards auto-publish geographic location flags without showing a flag dropdown, matching existing /bant/ behavior.
146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import { getBoardFlagDefinition, getBoardFlagDefinitions, type BoardFlagKind } from './board-flags';
|
|
import type { DirectoryCommunity } from './utils/directory-list-utils';
|
|
|
|
const GEOGRAPHIC_LOCATION_FLAG_VALUE = 'country:auto';
|
|
const NO_FLAG_VALUE = 'none';
|
|
const FLAG_CHALLENGE_ANSWER_PREFIX = 'bitsocial-flags:5chan:';
|
|
|
|
export interface CommentFlagSelectOption {
|
|
value: string;
|
|
label: string;
|
|
}
|
|
|
|
export interface CommentFlagRequest {
|
|
type: 'country' | BoardFlagKind;
|
|
code: string;
|
|
text: string;
|
|
}
|
|
|
|
interface CommentFlagChallengeRequest {
|
|
challengeAnswers: string[];
|
|
}
|
|
|
|
export interface CommentFlagPublishOptions {
|
|
challengeRequest: CommentFlagChallengeRequest | undefined;
|
|
flairs: CommentFlagRequest[] | undefined;
|
|
}
|
|
|
|
export type CommentFlagDirectory = Partial<Pick<DirectoryCommunity, 'directoryCode' | 'features' | 'title'>>;
|
|
|
|
const GEOGRAPHIC_LOCATION_OPTION: CommentFlagSelectOption = {
|
|
value: GEOGRAPHIC_LOCATION_FLAG_VALUE,
|
|
label: 'Geographic Location',
|
|
};
|
|
|
|
const NO_FLAG_OPTION: CommentFlagSelectOption = {
|
|
value: NO_FLAG_VALUE,
|
|
label: 'None',
|
|
};
|
|
|
|
/** Boards that always publish geographic location without showing a flag selector. */
|
|
const AUTO_GEOGRAPHIC_FLAG_DIRECTORY_CODES = new Set(['bant', 'int', 'sp']);
|
|
|
|
const getDirectoryCode = (directory: Pick<DirectoryCommunity, 'directoryCode' | 'title'> | undefined): string | undefined => {
|
|
const directoryCode = directory?.directoryCode?.trim().toLowerCase();
|
|
return directoryCode || directory?.title?.match(/^\/([^/]+)\//)?.[1]?.toLowerCase();
|
|
};
|
|
|
|
export const hasCommentFlagsForDirectory = (directory: CommentFlagDirectory | undefined): boolean => {
|
|
return directory?.features?.hasFlags === true;
|
|
};
|
|
|
|
const getBoardFlagOptions = (kind: BoardFlagKind): CommentFlagSelectOption[] =>
|
|
getBoardFlagDefinitions(kind).map((flag) => ({
|
|
value: `${flag.kind}:${flag.code}`,
|
|
label: flag.label,
|
|
}));
|
|
|
|
export const getCommentFlagOptionsForDirectory = (directory: CommentFlagDirectory | undefined): CommentFlagSelectOption[] => {
|
|
if (!hasCommentFlagsForDirectory(directory)) {
|
|
return [];
|
|
}
|
|
|
|
const directoryCode = getDirectoryCode(directory);
|
|
if (directoryCode && AUTO_GEOGRAPHIC_FLAG_DIRECTORY_CODES.has(directoryCode)) {
|
|
return [];
|
|
}
|
|
|
|
if (directoryCode === 'mlp') {
|
|
return [NO_FLAG_OPTION, ...getBoardFlagOptions('pony')];
|
|
}
|
|
|
|
if (directoryCode === 'pol') {
|
|
return [GEOGRAPHIC_LOCATION_OPTION, ...getBoardFlagOptions('pol')];
|
|
}
|
|
|
|
return [GEOGRAPHIC_LOCATION_OPTION];
|
|
};
|
|
|
|
export const getCommentFlagPublishOptionsForDirectory = (directory: CommentFlagDirectory | undefined, selectedValue?: string): CommentFlagPublishOptions => {
|
|
if (!hasCommentFlagsForDirectory(directory)) {
|
|
return {
|
|
challengeRequest: undefined,
|
|
flairs: undefined,
|
|
};
|
|
}
|
|
|
|
const directoryCode = getDirectoryCode(directory);
|
|
if (directoryCode && AUTO_GEOGRAPHIC_FLAG_DIRECTORY_CODES.has(directoryCode)) {
|
|
return getCommentFlagPublishOptionsFromSelection(GEOGRAPHIC_LOCATION_FLAG_VALUE);
|
|
}
|
|
|
|
const flagOptions = getCommentFlagOptionsForDirectory(directory);
|
|
if (flagOptions.length === 0) {
|
|
return {
|
|
challengeRequest: undefined,
|
|
flairs: undefined,
|
|
};
|
|
}
|
|
|
|
return getCommentFlagPublishOptionsFromSelection(selectedValue ?? flagOptions[0]?.value);
|
|
};
|
|
|
|
export const getCommentFlagRequestFromSelection = (value: string | undefined): CommentFlagRequest | undefined => {
|
|
if (!value || value === NO_FLAG_VALUE) {
|
|
return undefined;
|
|
}
|
|
|
|
if (value === GEOGRAPHIC_LOCATION_FLAG_VALUE) {
|
|
return {
|
|
type: 'country',
|
|
code: 'auto',
|
|
text: 'flag:country:auto',
|
|
};
|
|
}
|
|
|
|
const match = value.match(/^(pol|pony):([A-Z0-9]+)$/);
|
|
if (!match) {
|
|
return undefined;
|
|
}
|
|
|
|
const [, kind, code] = match;
|
|
const flag = getBoardFlagDefinition(kind, code);
|
|
return flag
|
|
? {
|
|
type: flag.kind,
|
|
code: flag.code,
|
|
text: `flag:${flag.kind}:${flag.code}`,
|
|
}
|
|
: undefined;
|
|
};
|
|
|
|
export const getCommentFlagPublishOptionsFromSelection = (value: string | undefined): CommentFlagPublishOptions => {
|
|
const flag = getCommentFlagRequestFromSelection(value);
|
|
return flag
|
|
? {
|
|
challengeRequest: {
|
|
challengeAnswers: [`${FLAG_CHALLENGE_ANSWER_PREFIX}${flag.text}`],
|
|
},
|
|
flairs: [flag],
|
|
}
|
|
: {
|
|
challengeRequest: undefined,
|
|
flairs: undefined,
|
|
};
|
|
};
|