diff --git a/apps/activitypub/package.json b/apps/activitypub/package.json index 2b1bf06618b..c80215962f5 100644 --- a/apps/activitypub/package.json +++ b/apps/activitypub/package.json @@ -1,6 +1,6 @@ { "name": "@tryghost/activitypub", - "version": "2.0.2", + "version": "2.0.3", "license": "MIT", "repository": { "type": "git", diff --git a/apps/activitypub/src/api/activitypub.ts b/apps/activitypub/src/api/activitypub.ts index 5f60c60de44..fdcb30ba393 100644 --- a/apps/activitypub/src/api/activitypub.ts +++ b/apps/activitypub/src/api/activitypub.ts @@ -105,6 +105,8 @@ export interface Notification { url: string; handle: string; avatarUrl: string | null; + followedByMe?: boolean; + followsMe?: boolean; }, post: null | { id: string; diff --git a/apps/activitypub/src/components/global/FollowButton.tsx b/apps/activitypub/src/components/global/FollowButton.tsx index 489796ed8a8..f63bf54cdb2 100644 --- a/apps/activitypub/src/components/global/FollowButton.tsx +++ b/apps/activitypub/src/components/global/FollowButton.tsx @@ -8,6 +8,8 @@ interface FollowButtonProps { following: boolean; handle: string; type?: 'primary' | 'secondary'; + variant?: 'default' | 'link'; + followsYou?: boolean; onFollow?: () => void; onUnfollow?: () => void; 'data-testid'?: string; @@ -19,6 +21,8 @@ const FollowButton: React.FC = ({ className, following, handle, + variant = 'default', + followsYou = false, onFollow = noop, onUnfollow = noop, 'data-testid': testId @@ -59,6 +63,31 @@ const FollowButton: React.FC = ({ setIsFollowing(following); }, [following]); + const buttonText = isFollowing ? 'Following' : (followsYou ? 'Follow back' : 'Follow'); + + if (variant === 'link') { + return ( + + ); + } + return ( ); }; diff --git a/apps/activitypub/src/views/Inbox/components/Reader.tsx b/apps/activitypub/src/views/Inbox/components/Reader.tsx index c9afa7e7a69..fc8398aa70c 100644 --- a/apps/activitypub/src/views/Inbox/components/Reader.tsx +++ b/apps/activitypub/src/views/Inbox/components/Reader.tsx @@ -13,6 +13,7 @@ import BackButton from '@src/components/global/BackButton'; import DeletedFeedItem from '@src/components/feed/DeletedFeedItem'; import FeedItem from '@src/components/feed/FeedItem'; import FeedItemStats from '@src/components/feed/FeedItemStats'; +import FollowButton from '@src/components/global/FollowButton'; import ProfilePreviewHoverCard from '@components/global/ProfilePreviewHoverCard'; import TableOfContents, {TOCItem} from '@src/components/feed/TableOfContents'; import articleBodyStyles from '@src/components/articleBodyStyles'; @@ -807,22 +808,30 @@ export const Reader: React.FC = ({
- -
-
- -
-
handleProfileClick(actor, navigate, e)}> -
- {isLoadingContent ? : actor.name} +
+ +
+
+
-
- {!isLoadingContent && {getUsername(actor)}} - {isLoadingContent ? : renderTimestamp(object, !object.authored)} +
handleProfileClick(actor, navigate, e)}> +
+ {isLoadingContent ? : actor.name} +
+
+ {!isLoadingContent && {getUsername(actor)}} + {isLoadingContent ? : renderTimestamp(object, !object.authored)} +
-
-
+ + {!object.authored && !isLoadingContent && ( + + )} +
const actorText = ( <> - + { @@ -329,7 +330,7 @@ const Notifications: React.FC = () => { ) } {group.actors.length > 1 && -
+
{!openStates[group.id || `${group.type}_${index}`] && group.actors.slice(0, maxAvatars).map((actor: ActorProperties) => ( { {group.actors.map((actor: ActorProperties) => (
{ e?.stopPropagation(); handleProfileClick(actor.handle, navigate); }} > - - {actor.name} - {actor.handle} +
+ + {actor.name} + {actor.handle} +
+ {group.type === 'follow' && !actor.followedByMe && ( + + )}
))}
@@ -396,14 +407,25 @@ const Notifications: React.FC = () => { : -
- - {group.actors.length < 2 && - <> - - {renderTimestamp(group, false)} - - } +
+
+ + {group.actors.length < 2 && + <> + + {renderTimestamp(group, false)} + + } +
+ {/* Follow button for singular follow, reply, and mention */} + {group.actors.length === 1 && (group.type === 'follow' || group.type === 'reply' || group.type === 'mention') && !group.actors[0].followedByMe && ( + + )}
}