import type { AnyProfileView, ChatBskyActorDefs, ChatBskyConvoDefs } from '@atcute/bluesky';
import { isBlockedOrBlocking } from '#/lib/moderation/blocked-and-muted';
import { recordUriToShareUrl } from '#/lib/routes/app-links';
import { toShortUrl } from '#/lib/utils/url';
import { m } from '#/paraglide/messages';
export type UserMessageInfo = {
message: string | null;
sentAt: string;
reportableMessage?: ChatBskyConvoDefs.MessageView;
isBlockedMessage: boolean;
};
/**
* resolves whether a DID is blocked in either direction within a conversation.
*
* @param did the DID to check for blocks.
* @param members the list of members fetched with the conversation.
* @param primaryProfile the profile used to check for optimistic block states.
* @returns true if the DID is blocked.
*/
export function isDidBlockedInConvo({
did,
members,
primaryProfile,
}: {
did: string | undefined;
members: ChatBskyActorDefs.ProfileViewBasic[];
primaryProfile?: AnyProfileView;
}): boolean {
if (!did) {
return false;
}
if (primaryProfile && primaryProfile.did === did) {
return !!isBlockedOrBlocking(primaryProfile);
}
const member = members.find((mem) => mem.did === did);
return member ? !!isBlockedOrBlocking(member) : false;
}
export function getMessageInfo({
convo,
currentAccountDid,
primaryProfile,
}: {
convo: ChatBskyConvoDefs.ConvoView;
currentAccountDid: string | undefined;
primaryProfile?: AnyProfileView;
}): UserMessageInfo | null {
if (convo.lastMessage?.$type !== 'chat.bsky.convo.defs#messageView') {
return null;
}
const lastMessage = convo.lastMessage;
const isFromMe = lastMessage.sender?.did === currentAccountDid;
const senderDid = lastMessage.sender?.did;
const sender = convo.members.find((mem) => mem.did === senderDid);
const name = sender?.handle ?? null;
const isGroup = convo.kind?.$type === 'chat.bsky.convo.defs#groupConvo';
const reportableMessage = isFromMe ? undefined : lastMessage;
const isBlockedMessage = isDidBlockedInConvo({
did: senderDid,
members: convo.members,
primaryProfile,
});
const prefix = (message: string) => {
if (isFromMe) {
return m['components.dms.message.preview.byYou']({ message });
} else if (isGroup && name) {
return m['components.dms.message.preview.named']({ message, name });
}
return message;
};
let message: string | null = null;
if (lastMessage.text) {
message = prefix(lastMessage.text);
} else if (lastMessage.embed) {
const defaultEmbeddedContentMessage = m['common.embed.content']();
if (lastMessage.embed.$type === 'app.bsky.embed.record#view') {
const embed = lastMessage.embed;
if (embed.record.$type === 'app.bsky.embed.record#viewRecord') {
const record = embed.record;
const href = recordUriToShareUrl(record.uri);
const short = href ? toShortUrl(href) : defaultEmbeddedContentMessage;
message = prefix(short);
} else {
message = prefix(defaultEmbeddedContentMessage);
}
} else if (lastMessage.embed.$type === 'chat.bsky.embed.joinLink#view') {
message = prefix(m['common.chat.inviteLink']());
} else {
message = prefix(defaultEmbeddedContentMessage);
}
}
return {
message,
sentAt: lastMessage.sentAt,
reportableMessage,
isBlockedMessage,
};
}