Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type { MergedWriteObject, WriteForm } from '../../../../contexts';
import { useWritePostContext } from '../../../../contexts';
import { defaultMarkdownCommands } from '../../../../hooks/input';
import { WriteFooter } from '../../write';
import { MAX_POST_TITLE_LENGTH } from '../../../../constants/post';

export const generateWritePostKey = (reference = 'create'): string =>
`write:post:${reference}`;
Expand All @@ -34,7 +35,6 @@ export const checkSavedProperty = (
const defaultFilename = 'thumbnail.png';

// Shared constants - remember to update them in daily-api
const MAX_TITLE_LENGTH = 250;
const MAX_CONTENT_LENGTH = 10_000;

interface WriteFreeformContentProps {
Expand Down Expand Up @@ -154,7 +154,7 @@ export function WriteFreeformContent({
required
defaultValue={draft?.title ?? fetchedPost?.title}
onInput={onFormUpdate}
maxLength={MAX_TITLE_LENGTH}
maxLength={MAX_POST_TITLE_LENGTH}
/>
</AlertPointer>
<MarkdownInput
Expand Down
13 changes: 13 additions & 0 deletions packages/shared/src/components/post/write/ShareLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useSourcePostModeration from '../../../hooks/source/useSourcePostModerati
import type { SourcePostModeration } from '../../../graphql/squads';
import { usePrompt } from '../../../hooks/usePrompt';
import { useWritePostContext } from '../../../contexts';
import { MAX_POST_COMMENTARY_LENGTH } from '../../../constants/post';

interface ShareLinkProps {
squad?: Squad;
Expand All @@ -34,6 +35,7 @@ const confirmSharingAgainPrompt = {
},
};


export function ShareLink({
squad,
className,
Expand Down Expand Up @@ -75,6 +77,10 @@ export function ShareLink({
onSuccess: async () => push(squad?.permalink),
});

// Character limit state
const commentaryLength = commentary?.length ?? 0;
const isCommentaryTooLong = commentaryLength > MAX_POST_COMMENTARY_LENGTH;

const onUpdateSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
if (!fetchedPost?.id || !squad) {
return null;
Expand Down Expand Up @@ -169,9 +175,16 @@ export function ShareLink({
enabledCommand={{ mention: true }}
showMarkdownGuide={false}
onValueUpdate={setCommentary}
maxInputLength={MAX_POST_COMMENTARY_LENGTH}
/>
{isCommentaryTooLong && (
<p className="text-text-tertiary typo-caption">
Maximum length is {MAX_POST_COMMENTARY_LENGTH} characters
</p>
)}
<WriteFooter
isLoading={isPosting || isPostingModeration || isPendingCreation}
disabled={isCommentaryTooLong}
/>
</form>
);
Expand Down
4 changes: 3 additions & 1 deletion packages/shared/src/components/post/write/WriteFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ interface WriteFooterProps {
isLoading?: boolean;
className?: string;
isPoll?: boolean;
disabled?: boolean;
}

export function WriteFooter({
isLoading,
className,
isPoll,
disabled,
}: WriteFooterProps): ReactElement {
const { sidebarRendered } = useSidebarRendered();
const { shouldShowCta, isEnabled, onToggle, onSubmitted } =
Expand Down Expand Up @@ -54,7 +56,7 @@ export function WriteFooter({
'ml-auto hidden w-full tablet:mt-0 tablet:w-32 laptop:flex',
shouldShowCta && 'mt-6',
)}
disabled={isLoading}
disabled={isLoading || disabled}
loading={isLoading}
onClick={onSubmitted}
>
Expand Down
38 changes: 38 additions & 0 deletions packages/shared/src/constants/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Post Constants

Single source of truth for post-related character limits.

## Constants

### `MAX_POST_TITLE_LENGTH = 250`

Maximum characters for post titles.

**Used in:** `WriteFreeformContent.tsx` (title field)

```typescript
import { MAX_POST_TITLE_LENGTH } from '../../../../constants/post';

<TextField maxLength={MAX_POST_TITLE_LENGTH} />
```

### `MAX_POST_COMMENTARY_LENGTH = 250`

Maximum characters for link commentary/descriptions.

**Used in:** `ShareLink.tsx` (commentary field + validation)

```typescript
import { MAX_POST_COMMENTARY_LENGTH } from '../../../constants/post';

// Validation
if (commentary.length > MAX_POST_COMMENTARY_LENGTH) return null;

// Component
<MarkdownInput maxInputLength={MAX_POST_COMMENTARY_LENGTH} />
```

## Notes

- **Backend sync required:** Keep these in sync with `daily-api` validation
- **Naming pattern:** `MAX_POST_[FIELD]_LENGTH`
2 changes: 2 additions & 0 deletions packages/shared/src/constants/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const MAX_POST_TITLE_LENGTH = 250;
export const MAX_POST_COMMENTARY_LENGTH = 250;