@river-build/sdk
Version:
For more details, visit the following resources:
173 lines • 7.5 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { PersistedObservable, persistedObservable } from '../../../observable/persistedObservable';
import { LoadPriority } from '../../../store/store';
import { MessageTimeline } from '../../timeline/timeline';
import { check, dlogger } from '@river-build/dlog';
import { isDefined } from '../../../check';
import { Members } from '../../members/members';
const logger = dlogger('csb:channel');
let Channel = class Channel extends PersistedObservable {
riverConnection;
spaceDapp;
timeline;
members;
constructor(id, spaceId, riverConnection, spaceDapp, store) {
super({ id, spaceId, isJoined: false }, store, LoadPriority.high);
this.riverConnection = riverConnection;
this.spaceDapp = spaceDapp;
this.timeline = new MessageTimeline(id, riverConnection.userId, riverConnection);
this.members = new Members(id, riverConnection, store);
}
onLoaded() {
this.riverConnection.registerView((client) => {
if (client.streams.has(this.data.id) &&
client.streams.get(this.data.id)?.view.isInitialized) {
this.onStreamInitialized(this.data.id);
}
client.on('streamInitialized', this.onStreamInitialized);
client.on('streamNewUserJoined', this.onStreamUserJoined);
client.on('streamUserLeft', this.onStreamUserLeft);
return () => {
client.off('streamInitialized', this.onStreamInitialized);
client.off('streamNewUserJoined', this.onStreamUserJoined);
client.off('streamUserLeft', this.onStreamUserLeft);
};
});
if (!this.data.metadata) {
// todo aellis this needs batching and retries, and should be updated on spaceChannelUpdated events
this.spaceDapp
.getChannelDetails(this.data.spaceId, this.data.id)
.then((metadata) => {
if (metadata) {
this.setData({ metadata });
}
})
.catch((error) => {
logger.error('failed to get channel details', { id: this.data.id, error });
});
}
}
/** Joins the channel. */
async join() {
const channelId = this.data.id;
await this.riverConnection.call(async (client) => {
await client.joinStream(channelId);
});
}
/** Sends a message to the channel.
* @param message - The message to send.
* @param options - Additional options for the message.
* @returns The event id of the message.
*/
async sendMessage(message, options) {
const channelId = this.data.id;
const result = await this.riverConnection.withStream(channelId).call((client) => {
return client.sendChannelMessage_Text(channelId, {
threadId: options?.threadId,
threadPreview: options?.threadId ? '🙉' : undefined,
replyId: options?.replyId,
replyPreview: options?.replyId ? '🙈' : undefined,
content: {
body: message,
mentions: options?.mentions ?? [],
attachments: options?.attachments ?? [],
},
});
});
return result;
}
/** Pins a message to the top of the channel.
* @param eventId - The event id of the message to pin.
* @returns The event id of the pin action.
*/
async pin(eventId) {
const channelId = this.data.id;
const result = await this.riverConnection
.withStream(channelId)
.call((client) => client.pin(channelId, eventId));
return result;
}
/** Unpins a message from the channel.
* @param eventId - The event id of the message to unpin.
* @returns The event id of the unpin action.
*/
async unpin(eventId) {
const channelId = this.data.id;
const result = await this.riverConnection
.withStream(channelId)
.call((client) => client.unpin(channelId, eventId));
return result;
}
/** Sends a reaction to a message.
* @param refEventId - The event id of the message to react to.
* @param reaction - The reaction to send. Can be any string, including emoji, unicode characters.
*/
async sendReaction(refEventId, reaction) {
const channelId = this.data.id;
const eventId = await this.riverConnection.call((client) => client.sendChannelMessage_Reaction(channelId, {
reaction,
refEventId,
}));
return eventId;
}
/** Redacts your own event.
* @param eventId - The event id of the message to redact
* @param reason - The reason for the redaction
*/
async redact(eventId, reason) {
const channelId = this.data.id;
const result = await this.riverConnection.withStream(channelId).call((client, stream) => {
const event = stream.view.events.get(eventId);
if (!event) {
throw new Error(`ref event not found: ${eventId}`);
}
if (event.creatorUserId !== this.riverConnection.userId) {
throw new Error(`You can only redact your own messages. Message creator: ${event.creatorUserId} - Your id: ${this.riverConnection.userId}`);
}
return client.sendChannelMessage_Redaction(channelId, {
refEventId: eventId,
reason,
});
});
return result;
}
/** Redacts any message as an admin.
* @param eventId - The event id of the message to redact
*/
async adminRedact(eventId) {
const channelId = this.data.id;
const result = await this.riverConnection
.withStream(channelId)
.call((client) => client.redactMessage(channelId, eventId));
return result;
}
onStreamInitialized = (streamId) => {
if (streamId === this.data.id) {
const stream = this.riverConnection.client?.stream(this.data.id);
check(isDefined(stream), 'stream is not defined');
const hasJoined = stream.view.getMembers().isMemberJoined(this.riverConnection.userId);
this.setData({ isJoined: hasJoined });
this.timeline.initialize(stream);
}
};
onStreamUserJoined = (streamId, userId) => {
if (streamId === this.data.id && userId === this.riverConnection.userId) {
this.setData({ isJoined: true });
}
};
onStreamUserLeft = (streamId, userId) => {
if (streamId === this.data.id && userId === this.riverConnection.userId) {
this.setData({ isJoined: false });
}
};
};
Channel = __decorate([
persistedObservable({ tableName: 'channel' })
], Channel);
export { Channel };
//# sourceMappingURL=channel.js.map