Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ const FeedItemRow = ({
const serialized = serializeEditorContent(content);
if (!serialized || !serialized.text.trim()) return;
if (id === item.id) {
onCommentUpdate?.(id, serialized.text, undefined, serialized.hasMention, permissions);
const text = item.annotationTimestampMarkup
? `${item.annotationTimestampMarkup} ${serialized.text}`
: serialized.text;
onCommentUpdate?.(id, text, undefined, serialized.hasMention, permissions);
return;
}
dispatchReplyEdit({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,44 @@ describe('elements/content-sidebar/activity-feed-v2/FeedItemRow', () => {

expect(mockedSeekVideoToMs).toHaveBeenCalledWith(8055);
});

test('should re-prepend timestamp markup when editing a video comment so the badge survives the update', () => {
mockedSerializeEditorContent.mockReturnValue({ hasMention: false, text: 'edited-text' });
const onCommentUpdate = jest.fn();
const timestampedComment: TransformedCommentItem = {
...mockComment,
annotationTarget: { timestamp: '0:08', type: AnnotationBadgeType.Frame },
annotationTimestampMarkup: '#[timestamp:8055,versionId:2390295731268]',
annotationTimestampMs: 8055,
};
render(<FeedItemRow {...defaultProps} item={timestampedComment} onCommentUpdate={onCommentUpdate} />);

lastThreadedAnnotationProps.onEdit?.('comment-1', { type: 'doc', content: [] });

expect(onCommentUpdate).toHaveBeenCalledWith(
'comment-1',
'#[timestamp:8055,versionId:2390295731268] edited-text',
undefined,
false,
commentPermissions,
);
});

test('should not modify edit text for a regular comment without timestamp markup', () => {
mockedSerializeEditorContent.mockReturnValue({ hasMention: false, text: 'edited-text' });
const onCommentUpdate = jest.fn();
render(<FeedItemRow {...defaultProps} item={mockComment} onCommentUpdate={onCommentUpdate} />);

lastThreadedAnnotationProps.onEdit?.('comment-1', { type: 'doc', content: [] });

expect(onCommentUpdate).toHaveBeenCalledWith(
'comment-1',
'edited-text',
undefined,
false,
commentPermissions,
);
});
});

describe('annotation rendering', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,13 +689,15 @@ describe('elements/content-sidebar/activity-feed-v2/transformers', () => {
const result = extractTimestampMarkup('#[timestamp:8055,versionId:2390295731268] wowo');
expect(result.cleanText).toBe('wowo');
expect(result.target).toEqual({ timestamp: '0:08', type: 'frame' });
expect(result.timestampMarkup).toBe('#[timestamp:8055,versionId:2390295731268]');
expect(result.timestampMs).toBe(8055);
});

test('should extract timestamp markup without versionId', () => {
const result = extractTimestampMarkup('#[timestamp:65000] hello');
expect(result.cleanText).toBe('hello');
expect(result.target).toEqual({ timestamp: '1:05', type: 'frame' });
expect(result.timestampMarkup).toBe('#[timestamp:65000]');
expect(result.timestampMs).toBe(65000);
});

Expand Down Expand Up @@ -759,6 +761,7 @@ describe('elements/content-sidebar/activity-feed-v2/transformers', () => {
expect(result!.type).toBe('comment');
if (result!.type === 'comment') {
expect(result.annotationTarget).toEqual({ timestamp: '0:08', type: 'frame' });
expect(result.annotationTimestampMarkup).toBe('#[timestamp:8055,versionId:2390295731268]');
expect(result.annotationTimestampMs).toBe(8055);
}
});
Expand All @@ -778,6 +781,7 @@ describe('elements/content-sidebar/activity-feed-v2/transformers', () => {
const result = transformFeedItem(comment as unknown as FeedItem);
if (result!.type === 'comment') {
expect(result.annotationTarget).toBeUndefined();
expect(result.annotationTimestampMarkup).toBeUndefined();
expect(result.annotationTimestampMs).toBeUndefined();
}
});
Expand Down
17 changes: 14 additions & 3 deletions src/elements/content-sidebar/activity-feed-v2/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ const TIMESTAMP_MARKUP_REGEX = /^#\[timestamp:(\d+)(?:,versionId:\d+)?\]\s*/;

export const extractTimestampMarkup = (
text: string,
): { cleanText: string; target?: AnnotationBadgeTargetType; timestampMs?: number } => {
): {
cleanText: string;
target?: AnnotationBadgeTargetType;
timestampMarkup?: string;
timestampMs?: number;
} => {
if (!text) return { cleanText: '' };
const match = text.match(TIMESTAMP_MARKUP_REGEX);
if (!match) return { cleanText: text };
Expand All @@ -60,7 +65,7 @@ export const extractTimestampMarkup = (
timestamp: convertMillisecondsToTimestamp(ms),
type: AnnotationBadgeType.Frame,
};
return { cleanText, target, timestampMs: ms };
return { cleanText, target, timestampMarkup: fullMatch.trimEnd(), timestampMs: ms };
};

const parseLine = (line: string, authorId: string): (MentionNode | TextNode)[] => {
Expand Down Expand Up @@ -292,11 +297,17 @@ export const transformFeedItem = (item: FeedItem, currentUserId?: string): Trans
const comment = item as unknown as Comment;
const commentIsResolved = comment.status === 'resolved';
const rawText = comment.tagged_message || comment.message || '';
const { cleanText, target: annotationTarget, timestampMs } = extractTimestampMarkup(rawText);
const {
cleanText,
target: annotationTarget,
timestampMarkup,
timestampMs,
} = extractTimestampMarkup(rawText);
const root = commentToTextMessage(comment, cleanText);
const replies = (comment.replies ?? []).map(reply => commentToTextMessage(reply));
return {
annotationTarget,
annotationTimestampMarkup: timestampMarkup,
annotationTimestampMs: timestampMs,
id: comment.id,
isResolved: commentIsResolved,
Expand Down
1 change: 1 addition & 0 deletions src/elements/content-sidebar/activity-feed-v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type ResolvedInfo = {

export type TransformedCommentItem = {
annotationTarget?: AnnotationBadgeTargetType;
annotationTimestampMarkup?: string;
annotationTimestampMs?: number;
id: string;
messages: TextMessageType[];
Expand Down
Loading