nicolium: mark unavailable parent posts correctly

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-03-30 22:55:16 +02:00
parent 95a4b828d8
commit 18b0c3ab81
4 changed files with 14 additions and 8 deletions

View File

@@ -8,10 +8,11 @@ interface ITombstone {
onMoveUp?: (statusId: string) => void | boolean;
onMoveDown?: (statusId: string) => void | boolean;
deleted?: boolean;
unavailable?: boolean;
}
/** Represents a deleted item. */
const Tombstone: React.FC<ITombstone> = ({ id, onMoveUp, onMoveDown, deleted }) => {
const Tombstone: React.FC<ITombstone> = ({ id, onMoveUp, onMoveDown, deleted, unavailable }) => {
const handlers = {
moveUp: () => onMoveUp?.(id),
moveDown: () => onMoveDown?.(id),
@@ -22,6 +23,11 @@ const Tombstone: React.FC<ITombstone> = ({ id, onMoveUp, onMoveDown, deleted })
<div className='focusable ⁂-status-tombstone' tabIndex={0}>
{deleted ? (
<FormattedMessage id='statuses.tombstone.deleted' defaultMessage='The post is deleted.' />
) : unavailable ? (
<FormattedMessage
id='statuses.tombstone.unavailable'
defaultMessage='The post is not visible to you.'
/>
) : (
<FormattedMessage
id='statuses.tombstone'

View File

@@ -292,7 +292,7 @@ const Thread = ({
);
}
if (id.endsWith('-tombstone')) {
if (id.endsWith('-tombstone') || id.endsWith('-unavailable')) {
return renderTombstone(id);
} else if (id.startsWith('末pending-')) {
return renderPendingStatus(id);

View File

@@ -69,7 +69,7 @@ const EventDiscussionPage: React.FC = () => {
const renderChildren = (list: Array<string>) =>
list.map((id) => {
if (id.endsWith('-tombstone')) {
if (id.endsWith('-tombstone') || id.endsWith('-unavailable')) {
return renderTombstone(id);
} else if (id.startsWith('末pending-')) {
return renderPendingStatus(id);

View File

@@ -7,18 +7,18 @@ import { findStatuses } from '@/queries/statuses/use-status';
import type { Context, Status } from 'pl-api';
/** Minimal status fields needed to process context. */
type ContextStatus = Pick<Status, 'id' | 'in_reply_to_id'>;
type ContextStatus = Pick<Status, 'id' | 'in_reply_to_id' | 'parent_visible'>;
/** Import a single status into the reducer, setting replies and replyTos. */
const importStatus = (state: State, status: ContextStatus, idempotencyKey?: string) => {
const { id, in_reply_to_id: inReplyToId } = status;
const { id, in_reply_to_id: inReplyToId, parent_visible: parentVisible } = status;
if (!inReplyToId) return;
const replies = state.replies[inReplyToId] || [];
const newReplies = [...new Set([...replies, id])].toSorted();
state.replies[inReplyToId] = newReplies;
state.inReplyTos[id] = inReplyToId;
state.inReplyTos[id] = parentVisible === false ? `${inReplyToId}-unavailable` : inReplyToId;
if (idempotencyKey) {
deletePendingStatus(state, status.in_reply_to_id, idempotencyKey);
@@ -34,8 +34,8 @@ const importStatuses = (state: State, statuses: ContextStatus[]) => {
/** Insert a fake status ID connecting descendant to ancestor. */
const insertTombstone = (state: State, ancestorId: string, descendantId: string) => {
const tombstoneId = `${descendantId}-tombstone`;
importStatus(state, { id: tombstoneId, in_reply_to_id: ancestorId });
importStatus(state, { id: descendantId, in_reply_to_id: tombstoneId });
importStatus(state, { id: tombstoneId, in_reply_to_id: ancestorId, parent_visible: false });
importStatus(state, { id: descendantId, in_reply_to_id: tombstoneId, parent_visible: false });
};
/** Find the highest level status from this statusId. */