mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Made inbox view easier to scan through (#21729)
ref https://linear.app/ghost/issue/AP-609/give-inbox-ui-more-room-to-breathe - Added more white space - Made more lines of text for titles and excerpts visible - Added estimated reading time - Updated feature image size and position
This commit is contained in:
parent
cdea73b873
commit
d32955b21e
5 changed files with 47 additions and 32 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@tryghost/admin-x-activitypub",
|
||||
"version": "0.3.22",
|
||||
"version": "0.3.23",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -86,7 +86,7 @@ const Inbox: React.FC<InboxProps> = ({layout}) => {
|
|||
</div>
|
||||
) : activities.length > 0 ? (
|
||||
<>
|
||||
<div className={`mx-auto flex items-start gap-8`}>
|
||||
<div className={`mx-auto flex min-h-[calc(100dvh_-_117px)] items-start gap-8`}>
|
||||
<div className='flex w-full min-w-0 flex-col items-center'>
|
||||
<div className={`flex w-full min-w-0 flex-col items-start ${layout === 'inbox' ? 'xxxl:max-w-[800px]' : 'max-w-[500px]'}`}>
|
||||
{layout === 'feed' && <div className='relative mx-[-12px] mb-4 mt-10 flex w-[calc(100%+24px)] items-center p-3'>
|
||||
|
|
|
@ -6,6 +6,7 @@ import APAvatar from '../global/APAvatar';
|
|||
|
||||
import FeedItemStats from './FeedItemStats';
|
||||
import clsx from 'clsx';
|
||||
import getReadingTime from '../../utils/get-reading-time';
|
||||
import getRelativeTimestamp from '../../utils/get-relative-timestamp';
|
||||
import getUsername from '../../utils/get-username';
|
||||
import stripHtml from '../../utils/strip-html';
|
||||
|
@ -93,7 +94,7 @@ export function renderFeedAttachment(object: ObjectProperties, layout: string) {
|
|||
function renderInboxAttachment(object: ObjectProperties) {
|
||||
const attachment = getAttachment(object);
|
||||
|
||||
const videoAttachmentStyles = 'ml-8 shrink-0 rounded-md h-[80px] w-[120px] relative';
|
||||
const videoAttachmentStyles = 'ml-8 shrink-0 rounded-md h-[91px] w-[121px] relative';
|
||||
const imageAttachmentStyles = clsx('object-cover outline outline-1 -outline-offset-1 outline-black/[0.05]', videoAttachmentStyles);
|
||||
|
||||
if (!attachment) {
|
||||
|
@ -391,25 +392,26 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
return (
|
||||
<>
|
||||
{object && (
|
||||
<div className='group/article relative -mx-4 -my-px flex min-h-[112px] min-w-0 cursor-pointer items-center justify-between rounded-md p-4 hover:bg-grey-75' data-layout='inbox' data-object-id={object.id} onClick={onClick}>
|
||||
<div className='flex min-h-[73px] w-full min-w-0 flex-col items-start justify-start'>
|
||||
<div className='z-10 mb-1 flex w-full min-w-0 items-center gap-1.5 text-base text-grey-700 group-hover/article:border-transparent'>
|
||||
<div className='group/article relative -mx-4 -my-px flex min-h-[112px] min-w-0 cursor-pointer flex-col justify-between rounded-md px-4 py-7 hover:bg-grey-75' data-layout='inbox' data-object-id={object.id} onClick={onClick}>
|
||||
<div className='z-10 mb-1.5 flex w-full min-w-0 items-center gap-1.5 text-base text-grey-700 group-hover/article:border-transparent'>
|
||||
<APAvatar author={author} size='2xs'/>
|
||||
<span className='min-w-0 truncate break-all font-medium text-grey-900' data-test-activity-heading>{author.name}</span>
|
||||
<span className='min-w-0 truncate'>{getUsername(author)}</span>
|
||||
<span className='shrink-0 whitespace-nowrap before:mr-1 before:content-["·"]' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
||||
<span className='min-w-0 truncate break-all font-medium text-grey-900' title={getUsername(author)} data-test-activity-heading>{author.name}</span>
|
||||
<span className='ml-auto shrink-0 whitespace-nowrap' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
||||
</div>
|
||||
<Heading className='mb-1 line-clamp-1 w-full max-w-[600px] text-[1.6rem] font-semibold leading-snug' level={5} data-test-activity-heading>
|
||||
<div className='flex'>
|
||||
<div className='flex min-h-[73px] w-full min-w-0 flex-col items-start justify-start gap-1'>
|
||||
<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)
|
||||
}}></span>
|
||||
)}
|
||||
</Heading>
|
||||
<div dangerouslySetInnerHTML={({__html: stripHtml(object.content)})} className='ap-note-content w-full max-w-[600px] truncate text-base leading-normal text-grey-700'></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-700'></div>
|
||||
<span className='mt-1 shrink-0 whitespace-nowrap leading-none text-grey-700'>{object.content && `${getReadingTime(object.content)}`}</span>
|
||||
</div>
|
||||
{renderInboxAttachment(object)}
|
||||
<div className='invisible absolute right-4 top-[9px] z-[49] flex flex-col gap-2 rounded-lg bg-white p-2 shadow-md-heavy group-hover/article:visible'>
|
||||
<div className='invisible absolute right-4 top-[22px] z-[49] flex gap-3 rounded-full bg-white px-3 py-2 shadow-md-heavy group-hover/article:visible'>
|
||||
<FeedItemStats
|
||||
commentCount={commentCount}
|
||||
layout={layout}
|
||||
|
@ -421,6 +423,7 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
|
|||
<Menu items={menuItems} open={menuIsOpen} position='end' setOpen={setMenuIsOpen} trigger={UserMenuTrigger}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -39,7 +39,7 @@ const FeedItemStats: React.FC<FeedItemStatsProps> = ({
|
|||
setTimeout(() => setIsClicked(false), 300);
|
||||
};
|
||||
|
||||
return (<div className={`flex ${(layout === 'inbox') ? 'flex-col gap-2' : 'gap-5'}`}>
|
||||
return (<div className={`flex ${(layout === 'inbox') ? 'gap-3' : 'gap-5'}`}>
|
||||
<div className='flex gap-1'>
|
||||
<Button
|
||||
className={`self-start text-grey-900 transition-opacity hover:opacity-60 ${isClicked ? 'bump' : ''} ${isLiked ? 'ap-red-heart text-red *:!fill-red hover:text-red' : ''}`}
|
||||
|
|
12
apps/admin-x-activitypub/src/utils/get-reading-time.ts
Normal file
12
apps/admin-x-activitypub/src/utils/get-reading-time.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
export default function getReadingTime(content: string): string {
|
||||
// Average reading speed (words per minute)
|
||||
const wordsPerMinute = 238;
|
||||
|
||||
const wordCount = content.replace(/<[^>]*>/g, '')
|
||||
.split(/\s+/)
|
||||
.filter(word => word.length > 0)
|
||||
.length;
|
||||
|
||||
const minutes = Math.ceil(wordCount / wordsPerMinute);
|
||||
return `${minutes} min read`;
|
||||
}
|
Loading…
Reference in a new issue