mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-25 02:31:59 -05:00
Handle null values for post content & excerpt in admin-x-activitypub (#21989)
Handle null values for post content & excerpt in admin-x-activitypub refs [TryGhost/ActivityPub#245](https://github.com/TryGhost/ActivityPub/pull/245) In [TryGhost/ActivityPub#245](https://github.com/TryGhost/ActivityPub/pull/245) we changed the service to allow for `null` values for the `content` & `excerpt` field. This means we could potentially be passing `null` values to `stripHtml` which would cause the app to crash. This commit ensures we always pass a string to `stripHtml` as well as updating the types to reflect what the value can be
This commit is contained in:
parent
ea127b29db
commit
20a1b64a15
5 changed files with 12 additions and 12 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@tryghost/admin-x-activitypub",
|
||||
"version": "0.3.42",
|
||||
"version": "0.3.43",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -148,7 +148,7 @@ const getGroupDescription = (group: GroupedActivity): JSX.Element => {
|
|||
return <>{actorText} liked your post <span className='font-semibold'>{group.object?.name || ''}</span></>;
|
||||
case ACTIVITY_TYPE.CREATE:
|
||||
if (group.object?.inReplyTo && typeof group.object?.inReplyTo !== 'string') {
|
||||
let content = stripHtml(group.object.inReplyTo.content);
|
||||
let content = stripHtml(group.object.inReplyTo.content || '');
|
||||
|
||||
// If the post has a name, use that instead of the content (short
|
||||
// form posts do not have a name)
|
||||
|
|
|
@ -660,11 +660,11 @@ const ArticleModal: React.FC<ArticleModalProps> = ({
|
|||
{object.type === 'Article' && (
|
||||
<div className='border-b border-grey-200 pb-8' id='object-content'>
|
||||
<ArticleBody
|
||||
excerpt={object?.preview?.content}
|
||||
excerpt={object?.preview?.content ?? ''}
|
||||
fontFamily={fontFamily}
|
||||
fontSize={FONT_SIZES[currentFontSizeIndex]}
|
||||
heading={object.name}
|
||||
html={object.content}
|
||||
html={object.content ?? ''}
|
||||
image={typeof object.image === 'string' ? object.image : object.image?.url}
|
||||
lineHeight={LINE_HEIGHTS[currentLineHeightIndex]}
|
||||
/>
|
||||
|
@ -728,7 +728,7 @@ const ArticleModal: React.FC<ArticleModalProps> = ({
|
|||
{modalSize === MODAL_SIZE_LG && object.type === 'Article' && (
|
||||
<div className='pointer-events-none sticky bottom-0 flex items-end justify-between px-10 pb-[42px]'>
|
||||
<div className='pointer-events-auto text-grey-600'>
|
||||
{getReadingTime(object.content)}
|
||||
{getReadingTime(object.content ?? '')}
|
||||
</div>
|
||||
<div className='pointer-events-auto text-grey-600 transition-all duration-200 ease-out'>
|
||||
{readingProgress}%
|
||||
|
|
|
@ -264,7 +264,7 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
<div className=''>
|
||||
{(object.type === 'Article') && renderFeedAttachment(object, layout)}
|
||||
{object.name && <Heading className='my-1 text-pretty leading-tight' level={5} data-test-activity-heading>{object.name}</Heading>}
|
||||
{(object.preview && object.type === 'Article') ? <div className='line-clamp-3 leading-tight'>{object.preview.content}</div> : <div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content text-pretty leading-[1.4285714286] tracking-[-0.006em] text-grey-900'></div>}
|
||||
{(object.preview && object.type === 'Article') ? <div className='line-clamp-3 leading-tight'>{object.preview.content}</div> : <div dangerouslySetInnerHTML={({__html: object.content ?? ''})} className='ap-note-content text-pretty leading-[1.4285714286] tracking-[-0.006em] text-grey-900'></div>}
|
||||
{(object.type === 'Note') && renderFeedAttachment(object, layout)}
|
||||
{(object.type === 'Article') && <Button
|
||||
className={`mt-3 self-start text-grey-900 transition-all hover:opacity-60`}
|
||||
|
@ -318,7 +318,7 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
<div className={`relative z-10 col-start-1 col-end-3 w-full gap-4`}>
|
||||
<div className='flex flex-col'>
|
||||
{object.name && <Heading className='mb-1 leading-tight' level={4} data-test-activity-heading>{object.name}</Heading>}
|
||||
<div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content-large text-pretty text-[1.6rem] tracking-[-0.011em] text-grey-900'></div>
|
||||
<div dangerouslySetInnerHTML={({__html: object.content ?? ''})} className='ap-note-content-large text-pretty text-[1.6rem] tracking-[-0.011em] text-grey-900'></div>
|
||||
{renderFeedAttachment(object, layout)}
|
||||
<div className='space-between ml-[-7px] mt-3 flex'>
|
||||
<FeedItemStats
|
||||
|
@ -372,7 +372,7 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
<div className='flex flex-col'>
|
||||
{(object.type === 'Article') && renderFeedAttachment(object, layout)}
|
||||
{object.name && <Heading className='my-1 text-pretty leading-tight' level={5} data-test-activity-heading>{object.name}</Heading>}
|
||||
{(object.preview && object.type === 'Article') ? <div className='line-clamp-3 leading-tight'>{object.preview.content}</div> : <div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content text-pretty tracking-[-0.006em] text-grey-900'></div>}
|
||||
{(object.preview && object.type === 'Article') ? <div className='line-clamp-3 leading-tight'>{object.preview.content}</div> : <div dangerouslySetInnerHTML={({__html: object.content ?? ''})} className='ap-note-content text-pretty tracking-[-0.006em] text-grey-900'></div>}
|
||||
{(object.type === 'Note') && renderFeedAttachment(object, layout)}
|
||||
{(object.type === 'Article') && <Button
|
||||
className={`mt-3 self-start text-grey-900 transition-all hover:opacity-60`}
|
||||
|
@ -423,11 +423,11 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
<Heading className='w-full max-w-[600px] text-pretty text-[1.6rem] font-semibold leading-tight' level={5} data-test-activity-heading>
|
||||
{object.name ? object.name : (
|
||||
<span dangerouslySetInnerHTML={{
|
||||
__html: stripHtml(object.content)
|
||||
__html: stripHtml(object.content || '')
|
||||
}}></span>
|
||||
)}
|
||||
</Heading>
|
||||
<div dangerouslySetInnerHTML={({__html: stripHtml(object.preview?.content ?? object.content)})} className='ap-note-content line-clamp-2 w-full max-w-[600px] text-pretty text-base leading-normal text-grey-800'></div>
|
||||
<div dangerouslySetInnerHTML={({__html: stripHtml(object.preview?.content ?? object.content ?? '')})} className='ap-note-content line-clamp-2 w-full max-w-[600px] text-pretty text-base leading-normal text-grey-800'></div>
|
||||
<span className='mt-1 shrink-0 whitespace-nowrap text-sm leading-none text-grey-600'>{object.content && `${getReadingTime(object.content)}`}</span>
|
||||
</div>
|
||||
<div className='invisible absolute right-4 top-1/2 z-[49] flex -translate-y-1/2 flex-col rounded-full bg-white p-1 shadow-md group-hover/article:visible'>
|
||||
|
|
|
@ -11,7 +11,7 @@ export type ObjectProperties = {
|
|||
'@context': string | (string | object)[];
|
||||
type: 'Article' | 'Link' | 'Note';
|
||||
name: string;
|
||||
content: string;
|
||||
content: string | null;
|
||||
url?: string | undefined;
|
||||
attributedTo?: object | string | object[] | undefined;
|
||||
image?: string | {
|
||||
|
@ -20,7 +20,7 @@ export type ObjectProperties = {
|
|||
type?: string;
|
||||
};
|
||||
published?: string;
|
||||
preview?: {type: string, content: string};
|
||||
preview?: {type: string, content: string | null};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[x: string]: any;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue