'use client'; import React, { FC, Fragment, useMemo } from 'react'; import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store'; import { useShallow } from 'zustand/react/shallow'; import clsx from 'clsx'; import SafeImage from '@gitroom/react/helpers/safe.image'; import { capitalize } from 'lodash'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { hasLinks } from '@gitroom/helpers/utils/strip.links'; const Valid: FC = () => { return ( ); }; const Invalid: FC = () => { return ( ); }; export const InformationComponent: FC<{ chars: Record; totalChars: number; totalAllowedChars: number; isPicture: boolean; text?: string; }> = ({ totalChars, totalAllowedChars, chars, isPicture, text }) => { const t = useT(); const { isGlobal, selectedIntegrations, internal, currentIntegration } = useLaunchStore( useShallow((state) => ({ isGlobal: state.current === 'global', selectedIntegrations: state.selectedIntegrations, internal: state.internal, currentIntegration: state.integrations.find( (p) => p.id === state.current ), })) ); const stripLinkNames = useMemo(() => { if (!hasLinks(text)) { return [] as string[]; } if (!isGlobal) { return currentIntegration?.stripLinks ? [currentIntegration.name] : []; } return selectedIntegrations .filter((p) => p.integration.stripLinks) .map((p) => p.integration.name); }, [text, isGlobal, currentIntegration, selectedIntegrations]); const showStripLinkWarning = stripLinkNames.length > 0; const isInternal = useMemo(() => { if (!isGlobal) { return []; } return selectedIntegrations.map((p) => { const findIt = internal.find( (a) => a.integration.id === p.integration.id ); return !!findIt; }); }, [isGlobal, internal, selectedIntegrations]); const isValid = useMemo(() => { if (showStripLinkWarning) { return false; } if (!isPicture && !totalChars) { return false; } if (totalChars > totalAllowedChars && !isGlobal) { return false; } if (totalChars <= totalAllowedChars && !isGlobal) { return true; } if ( selectedIntegrations.some((p, index) => { if (isInternal[index]) { return false; } return totalChars > (chars?.[p.integration.id] || 0); }) ) { return false; } return true; }, [ totalAllowedChars, totalChars, isInternal, isPicture, chars, showStripLinkWarning, ]); const globalDisplayLimit = useMemo(() => { if (!isGlobal || !selectedIntegrations.length) { return null; } // Get all limits from non-internal integrations, sorted ascending const limits = selectedIntegrations .map((p, index) => ({ limit: chars?.[p.integration.id] || 0, isInternal: isInternal[index], })) .filter((item) => !item.isInternal && item.limit > 0) .map((item) => item.limit) .sort((a, b) => a - b); if (!limits.length) { return null; } // Find the smallest limit that hasn't been exceeded yet // If all are exceeded, show the smallest one const validLimit = limits.find((limit) => totalChars <= limit); return validLimit ?? limits[0]; }, [isGlobal, selectedIntegrations, chars, isInternal, totalChars]); return (
{isValid ? : } {!isGlobal && (
{totalChars}/{totalAllowedChars}
)} {isGlobal && globalDisplayLimit !== null && (
{totalChars}/{globalDisplayLimit}
)} {((isGlobal && selectedIntegrations.length) || !isValid) && ( )} {((isGlobal && selectedIntegrations.length) || !isValid) && ( )}
); };