diff --git a/src/modules/cards/tests/utils/InMemoryCardQueryRepository.ts b/src/modules/cards/tests/utils/InMemoryCardQueryRepository.ts
index 80786021..90b58c28 100644
--- a/src/modules/cards/tests/utils/InMemoryCardQueryRepository.ts
+++ b/src/modules/cards/tests/utils/InMemoryCardQueryRepository.ts
@@ -156,6 +156,7 @@ export class InMemoryCardQueryRepository implements ICardQueryRepository {
return {
id: card.cardId.getStringValue(),
type: CardTypeEnum.URL,
+ uri: card.publishedRecordId?.uri,
url: card.content.urlContent.url.value,
cardContent: {
url: card.content.urlContent.url.value,
diff --git a/src/webapp/components/landing/activityCard/ActivityCard.tsx b/src/webapp/components/landing/activityCard/ActivityCard.tsx
index b5b19288..adbfa3a9 100644
--- a/src/webapp/components/landing/activityCard/ActivityCard.tsx
+++ b/src/webapp/components/landing/activityCard/ActivityCard.tsx
@@ -13,6 +13,7 @@ import { getRelativeTime } from '@/lib/utils/time';
interface Props {
id: string;
url: string;
+ uri?: string;
cardContent: UrlCard['cardContent'];
note?: UrlCard['note'];
cardAuthor?: User;
@@ -86,7 +87,11 @@ export default function ActivityCard(props: Props) {
withBorder
>
-
+
diff --git a/src/webapp/components/landing/recentActivity/RecentActivity.tsx b/src/webapp/components/landing/recentActivity/RecentActivity.tsx
index c4970934..a41c74a6 100644
--- a/src/webapp/components/landing/recentActivity/RecentActivity.tsx
+++ b/src/webapp/components/landing/recentActivity/RecentActivity.tsx
@@ -74,6 +74,7 @@ export default async function RecentActivity() {
-
+
{settings.tinkerMode && (
diff --git a/src/webapp/lib/utils/margin.ts b/src/webapp/lib/utils/margin.ts
index 6616dacf..49c623f0 100644
--- a/src/webapp/lib/utils/margin.ts
+++ b/src/webapp/lib/utils/margin.ts
@@ -11,14 +11,17 @@ export function isMarginUri(uri?: string): boolean {
/**
* Extract Margin URL from an AT Protocol URI
* @param uri - The AT Protocol URI (e.g., "at://did:plc:xyz/at.margin.bookmark/3mdjtvntgej2v")
- * @param handle - The user's handle (e.g., "alice.bsky.social")
+ * @param handle - The user's handle (e.g., "alice.bsky.social") - optional, will use DID if not provided
* @returns The Margin URL or null if not a valid Margin URI
* @example
* getMarginUrl("at://did:plc:xyz/at.margin.bookmark/3mdjtvntgej2v", "alice.bsky.social")
* // returns "https://margin.at/alice.bsky.social/bookmark/3mdjtvntgej2v"
+ *
+ * getMarginUrl("at://did:plc:xyz/at.margin.bookmark/3mdjtvntgej2v")
+ * // returns "https://margin.at/did:plc:xyz/bookmark/3mdjtvntgej2v"
*/
export function getMarginUrl(uri?: string, handle?: string): string | null {
- if (!uri || !handle || !isMarginUri(uri)) return null;
+ if (!uri || !isMarginUri(uri)) return null;
// URI format: at://did:plc:xyz/at.margin.{collection|bookmark}/{rkey}
const parts = uri.split('/');
@@ -30,5 +33,8 @@ export function getMarginUrl(uri?: string, handle?: string): string | null {
// Extract the type from collection name
const type = collection.replace('at.margin.', ''); // "bookmark" or "collection"
- return `https://margin.at/${handle}/${type}/${rkey}`;
+ // Use handle if provided, otherwise extract DID from URI
+ const identifier = handle || parts[2]; // parts[2] is the DID from "at://did:plc:xyz/..."
+
+ return `https://margin.at/${identifier}/${type}/${rkey}`;
}