@towns-protocol/sdk
Version:
For more details, visit the following resources:
160 lines • 6.19 kB
JavaScript
import { GroupMentionType, MessageInteractionType, } from '@towns-protocol/proto';
import { addressFromUserId } from './id';
import { bin_fromHexString, bin_toHexString, check } from '@towns-protocol/dlog';
import { isDefined } from './check';
import { bytesToHex } from 'ethereum-cryptography/utils';
import { RiverTimelineEvent } from './views/models/timelineTypes';
/**
* Unsafe way to create tags. Possibly used in scenarios where we dont have access to the stream view.
* Usages of this function may create messages with the wrong tags.
*/
export function unsafe_makeTags(message) {
return {
messageInteractionType: getMessageInteractionType(message),
groupMentionTypes: getGroupMentionTypes(message),
mentionedUserAddresses: getMentionedUserAddresses(message),
participatingUserAddresses: [],
threadId: message.payload.case === 'post'
? message.payload.value.threadId
? bin_fromHexString(message.payload.value.threadId)
: undefined
: undefined,
};
}
export function makeTags(message, streamView) {
return {
messageInteractionType: getMessageInteractionType(message),
groupMentionTypes: getGroupMentionTypes(message),
mentionedUserAddresses: getMentionedUserAddresses(message),
participatingUserAddresses: getParticipatingUserAddresses(message, streamView),
threadId: getThreadId(message, streamView),
};
}
export function makeTipTags(event, toUserId, streamView) {
check(isDefined(streamView), 'stream not found');
return {
messageInteractionType: MessageInteractionType.TIP,
groupMentionTypes: [],
mentionedUserAddresses: [],
participatingUserAddresses: [addressFromUserId(toUserId)],
threadId: getParentThreadId(event.messageId, streamView),
};
}
export function makeTransferTags(event, streamView) {
check(isDefined(streamView), 'stream not found');
return {
messageInteractionType: MessageInteractionType.TRADE,
groupMentionTypes: [],
mentionedUserAddresses: [],
participatingUserAddresses: participantsFromParentEventId(bin_toHexString(event.messageId), streamView),
threadId: getParentThreadId(bytesToHex(event.messageId), streamView),
};
}
function getThreadId(message, streamView) {
switch (message.payload.case) {
case 'post':
if (message.payload.value.threadId) {
return bin_fromHexString(message.payload.value.threadId);
}
break;
case 'reaction':
return getParentThreadId(message.payload.value.refEventId, streamView);
case 'edit':
return getParentThreadId(message.payload.value.refEventId, streamView);
case 'redaction':
return getParentThreadId(message.payload.value.refEventId, streamView);
default:
break;
}
return undefined;
}
function getMessageInteractionType(message) {
switch (message.payload.case) {
case 'reaction':
return MessageInteractionType.REACTION;
case 'post':
if (message.payload.value.threadId) {
return MessageInteractionType.REPLY;
}
else if (message.payload.value.replyId) {
return MessageInteractionType.REPLY;
}
else {
return MessageInteractionType.POST;
}
case 'edit':
return MessageInteractionType.EDIT;
case 'redaction':
return MessageInteractionType.REDACTION;
default:
return MessageInteractionType.UNSPECIFIED;
}
}
function getGroupMentionTypes(message) {
const types = [];
if (message.payload.case === 'post' &&
message.payload.value.content.case === 'text' &&
message.payload.value.content.value.mentions.find((m) => m.mentionBehavior.case === 'atChannel')) {
types.push(GroupMentionType.AT_CHANNEL);
}
return types;
}
function getMentionedUserAddresses(message) {
if (message.payload.case === 'post' && message.payload.value.content.case === 'text') {
return message.payload.value.content.value.mentions
.filter((m) => m.mentionBehavior.case === undefined && m.userId.length > 0)
.map((m) => addressFromUserId(m.userId));
}
return [];
}
function getParticipatingUserAddresses(message, streamView) {
switch (message.payload.case) {
case 'reaction': {
const refEventId = message.payload.value.refEventId;
const event = streamView.timeline.find((x) => x.eventId === refEventId);
if (event) {
return [addressFromUserId(event.sender.id)];
}
return [];
}
case 'post': {
const parentId = message.payload.value.threadId || message.payload.value.replyId;
if (parentId) {
return participantsFromParentEventId(parentId, streamView);
}
return [];
}
default:
return [];
}
}
function participantsFromParentEventId(parentId, streamView) {
const participating = new Set();
const parentEvent = streamView.timeline.find((x) => x.eventId === parentId);
if (parentEvent && parentEvent.sender.id) {
participating.add(addressFromUserId(parentEvent.sender.id));
}
streamView.timeline.forEach((event) => {
if (event.content?.kind === RiverTimelineEvent.ChannelMessage &&
event.content.threadId === parentId) {
participating.add(addressFromUserId(event.sender.id));
}
});
return Array.from(participating);
}
function getParentThreadId(eventId, streamView) {
if (!eventId) {
return undefined;
}
const event = streamView.timeline.find((x) => x.eventId === eventId);
if (!event) {
return undefined;
}
if (event.content?.kind === RiverTimelineEvent.ChannelMessage) {
if (event.content.threadId) {
return bin_fromHexString(event.content.threadId);
}
}
return undefined;
}
//# sourceMappingURL=tags.js.map