Files
ignacionelson 6e47d76ba6 ProjectSend 2.0.0
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.

This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.

Free software under the GNU General Public License v2, or (at your
option) any later version.
2026-08-14 01:38:12 -03:00

46 lines
1.7 KiB
TypeScript

import { router } from '@inertiajs/react';
import { CommentComposer } from '@/components/comments/comment-composer';
import { CommentList } from '@/components/comments/comment-list';
import { useFileComments } from '@/hooks/use-file-comments';
/**
* A whole comment thread — the list and the composer — with the hook
* already wired.
*
* This is the piece a theme shell wraps in its own chrome, and the piece
* the staff details panel drops straight in. A shell decides whether it is
* a dialog, a sheet, a collapsible row or an inline block; it never
* decides what a comment looks like or how one is written.
*/
export function CommentThread({
fileId,
endpoint,
enabled = true,
dense = false,
}: {
fileId?: number;
endpoint?: string;
enabled?: boolean;
dense?: boolean;
}) {
// Comment counts, unread dots and pending badges are rendered from the
// page's own props, not from this component — so a comment posted here
// leaves the row behind it showing a stale number until something
// re-fetches them. Doing it once here means no surface has to remember
// to; the alternative was the same callback threaded through four theme
// shells and the details panel.
//
// No `only:` — the prop holding the counts is named differently on each
// surface (and the public page has none), and one refetch per posted
// comment is not worth knowing all of them.
const comments = useFileComments({ fileId, endpoint, enabled, onChanged: () => router.reload() });
return (
<div className="grid gap-4">
<CommentList comments={comments} dense={dense} />
<CommentComposer comments={comments} />
</div>
);
}