0
Fork 0
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:
Djordje Vlaisavljevic 2024-11-26 17:35:25 +00:00 committed by GitHub
parent cdea73b873
commit d32955b21e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 32 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "@tryghost/admin-x-activitypub", "name": "@tryghost/admin-x-activitypub",
"version": "0.3.22", "version": "0.3.23",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -86,7 +86,7 @@ const Inbox: React.FC<InboxProps> = ({layout}) => {
</div> </div>
) : activities.length > 0 ? ( ) : 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-center'>
<div className={`flex w-full min-w-0 flex-col items-start ${layout === 'inbox' ? 'xxxl:max-w-[800px]' : 'max-w-[500px]'}`}> <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'> {layout === 'feed' && <div className='relative mx-[-12px] mb-4 mt-10 flex w-[calc(100%+24px)] items-center p-3'>

View file

@ -6,6 +6,7 @@ import APAvatar from '../global/APAvatar';
import FeedItemStats from './FeedItemStats'; import FeedItemStats from './FeedItemStats';
import clsx from 'clsx'; import clsx from 'clsx';
import getReadingTime from '../../utils/get-reading-time';
import getRelativeTimestamp from '../../utils/get-relative-timestamp'; import getRelativeTimestamp from '../../utils/get-relative-timestamp';
import getUsername from '../../utils/get-username'; import getUsername from '../../utils/get-username';
import stripHtml from '../../utils/strip-html'; import stripHtml from '../../utils/strip-html';
@ -93,7 +94,7 @@ export function renderFeedAttachment(object: ObjectProperties, layout: string) {
function renderInboxAttachment(object: ObjectProperties) { function renderInboxAttachment(object: ObjectProperties) {
const attachment = getAttachment(object); 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); const imageAttachmentStyles = clsx('object-cover outline outline-1 -outline-offset-1 outline-black/[0.05]', videoAttachmentStyles);
if (!attachment) { if (!attachment) {
@ -391,34 +392,36 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type, comment
return ( return (
<> <>
{object && ( {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='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='flex min-h-[73px] w-full min-w-0 flex-col items-start justify-start'> <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'>
<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'> <APAvatar author={author} size='2xs'/>
<APAvatar author={author} size='2xs'/> <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='min-w-0 truncate break-all font-medium text-grey-900' data-test-activity-heading>{author.name}</span> <span className='ml-auto shrink-0 whitespace-nowrap' title={`${timestamp}`}>{getRelativeTimestamp(date)}</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>
</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>
{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> </div>
{renderInboxAttachment(object)} <div className='flex'>
<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='flex min-h-[73px] w-full min-w-0 flex-col items-start justify-start gap-1'>
<FeedItemStats <Heading className='w-full max-w-[600px] text-pretty text-[1.6rem] font-semibold leading-tight' level={5} data-test-activity-heading>
commentCount={commentCount} {object.name ? object.name : (
layout={layout} <span dangerouslySetInnerHTML={{
likeCount={1} __html: stripHtml(object.content)
object={object} }}></span>
onCommentClick={onCommentClick} )}
onLikeClick={onLikeClick} </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-700'></div>
<Menu items={menuItems} open={menuIsOpen} position='end' setOpen={setMenuIsOpen} trigger={UserMenuTrigger}/> <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-[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}
likeCount={1}
object={object}
onCommentClick={onCommentClick}
onLikeClick={onLikeClick}
/>
<Menu items={menuItems} open={menuIsOpen} position='end' setOpen={setMenuIsOpen} trigger={UserMenuTrigger}/>
</div>
</div> </div>
</div> </div>
)} )}

View file

@ -39,7 +39,7 @@ const FeedItemStats: React.FC<FeedItemStatsProps> = ({
setTimeout(() => setIsClicked(false), 300); 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'> <div className='flex gap-1'>
<Button <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' : ''}`} className={`self-start text-grey-900 transition-opacity hover:opacity-60 ${isClicked ? 'bump' : ''} ${isLiked ? 'ap-red-heart text-red *:!fill-red hover:text-red' : ''}`}

View 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`;
}