feat: expose more apis
This commit is contained in:
@@ -26,11 +26,15 @@ import { UsersActions } from '../../../../store/users/users.actions';
|
||||
import { selectAllUsers, selectCurrentUser } from '../../../../store/users/users.selectors';
|
||||
import type {
|
||||
PluginApiAvatarUpdate,
|
||||
PluginApiActionContext,
|
||||
PluginApiActionSource,
|
||||
PluginApiChannelRequest,
|
||||
PluginApiCustomStreamRequest,
|
||||
PluginApiMessageAsPluginUserRequest,
|
||||
PluginApiServerSettingsUpdate,
|
||||
TojuClientPluginApi
|
||||
PluginApiTypingEvent,
|
||||
TojuClientPluginApi,
|
||||
TojuPluginDisposable
|
||||
} from '../../domain/models/plugin-api.models';
|
||||
import { PluginCapabilityService } from './plugin-capability.service';
|
||||
import { PluginLoggerService } from './plugin-logger.service';
|
||||
@@ -122,6 +126,9 @@ export class PluginClientApiService {
|
||||
info: (message, data) => this.logger.info(pluginId, message, data),
|
||||
warn: (message, data) => this.logger.warn(pluginId, message, data)
|
||||
},
|
||||
context: {
|
||||
getCurrent: () => this.createActionContext('manual')
|
||||
},
|
||||
clientData: {
|
||||
read: async (key) => {
|
||||
requireCapability('storage.local');
|
||||
@@ -183,6 +190,14 @@ export class PluginClientApiService {
|
||||
requireCapability('messages.send');
|
||||
this.receivePluginUserMessage(pluginId, request);
|
||||
},
|
||||
setTyping: (isTyping, channelId) => {
|
||||
requireCapability('messages.send');
|
||||
this.setTyping(pluginId, isTyping, channelId);
|
||||
},
|
||||
subscribeTyping: (handler) => {
|
||||
requireCapability('messages.read');
|
||||
return this.subscribeTyping(pluginId, handler);
|
||||
},
|
||||
sync: (messages) => {
|
||||
requireCapability('messages.sync');
|
||||
this.store.dispatch(MessagesActions.syncMessages({ messages }));
|
||||
@@ -402,6 +417,24 @@ export class PluginClientApiService {
|
||||
});
|
||||
}
|
||||
|
||||
createActionContext(source: PluginApiActionSource): PluginApiActionContext {
|
||||
const user = this.currentUser() ?? null;
|
||||
const server = this.currentRoom();
|
||||
const channels = this.currentRoomChannels();
|
||||
const activeChannelId = this.activeChannelId() ?? 'general';
|
||||
const voiceChannelId = user?.voiceState?.roomId ?? null;
|
||||
|
||||
return {
|
||||
server,
|
||||
source,
|
||||
textChannel: channels.find((channel) => channel.type === 'text' && channel.id === activeChannelId) ?? null,
|
||||
user,
|
||||
voiceChannel: voiceChannelId
|
||||
? channels.find((channel) => channel.type === 'voice' && channel.id === voiceChannelId) ?? null
|
||||
: null
|
||||
};
|
||||
}
|
||||
|
||||
private assertDeclaredEvent(manifest: TojuPluginManifest, eventName: string): void {
|
||||
const declared = manifest.events?.some((event) => event.eventName === eventName) ?? false;
|
||||
|
||||
@@ -544,6 +577,71 @@ export class PluginClientApiService {
|
||||
return message;
|
||||
}
|
||||
|
||||
private setTyping(pluginId: string, isTyping: boolean, channelId?: string): void {
|
||||
const roomId = this.requireRoomId();
|
||||
|
||||
try {
|
||||
this.realtime.sendRawMessage({
|
||||
type: 'typing',
|
||||
serverId: roomId,
|
||||
channelId: channelId ?? this.activeChannelId() ?? 'general',
|
||||
isTyping
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
this.logger.warn(pluginId, 'Failed to publish typing state', error);
|
||||
}
|
||||
}
|
||||
|
||||
private subscribeTyping(pluginId: string, handler: (event: PluginApiTypingEvent) => void): TojuPluginDisposable {
|
||||
const subscription = new Subscription();
|
||||
|
||||
subscription.add(this.realtime.onSignalingMessage.subscribe((message) => {
|
||||
const record = message as Record<string, unknown>;
|
||||
|
||||
if (record['type'] !== 'user_typing') {
|
||||
return;
|
||||
}
|
||||
|
||||
const serverId = typeof record['serverId'] === 'string' ? record['serverId'] : '';
|
||||
const currentServer = this.currentRoom();
|
||||
|
||||
if (!serverId || serverId !== currentServer?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = typeof record['oderId'] === 'string' ? record['oderId'] : '';
|
||||
const displayName = typeof record['displayName'] === 'string' ? record['displayName'] : userId;
|
||||
const channelId = typeof record['channelId'] === 'string' && record['channelId'].trim()
|
||||
? record['channelId'].trim()
|
||||
: 'general';
|
||||
const user = this.users().find((entry) => entry.oderId === userId || entry.id === userId) ?? null;
|
||||
const channels = this.currentRoomChannels();
|
||||
|
||||
handler({
|
||||
channelId,
|
||||
displayName,
|
||||
isTyping: record['isTyping'] !== false,
|
||||
server: currentServer,
|
||||
serverId,
|
||||
textChannel: channels.find((channel) => channel.type === 'text' && channel.id === channelId) ?? null,
|
||||
user,
|
||||
userId,
|
||||
voiceChannel: user?.voiceState?.roomId
|
||||
? channels.find((channel) => channel.type === 'voice' && channel.id === user.voiceState?.roomId) ?? null
|
||||
: null
|
||||
});
|
||||
}));
|
||||
|
||||
this.logger.info(pluginId, 'Subscribed to typing events');
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
subscription.unsubscribe();
|
||||
this.logger.info(pluginId, 'Unsubscribed from typing events');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private persistPluginMessage(pluginId: string, message: Message): void {
|
||||
void this.db.saveMessage(message).catch((error: unknown) => {
|
||||
this.logger.warn(pluginId, 'Failed to persist plugin message', error);
|
||||
|
||||
Reference in New Issue
Block a user