Move toju-app into own its folder
This commit is contained in:
31
toju-app/src/app/shared-kernel/README.md
Normal file
31
toju-app/src/app/shared-kernel/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Shared Kernel
|
||||
|
||||
Types and constants that are **intentionally shared** across multiple bounded
|
||||
contexts (domains). Changing anything here affects every consumer, so changes
|
||||
require coordination.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Contents |
|
||||
|---|---|
|
||||
| `user.models.ts` | `User`, `UserStatus`, `UserRole`, `RoomMember` |
|
||||
| `room.models.ts` | `Room`, `RoomSettings`, `RoomPermissions`, `Channel`, `ChannelType` |
|
||||
| `message.models.ts` | `Message`, `Reaction`, `DELETED_MESSAGE_CONTENT` |
|
||||
| `moderation.models.ts` | `BanEntry` |
|
||||
| `voice-state.models.ts` | `VoiceState`, `ScreenShareState` |
|
||||
| `chat-events.ts` | `ChatEventType`, `ChatEvent`, `ChatInventoryItem` |
|
||||
| `media-preferences.ts` | `LatencyProfile`, `ScreenShareQuality`, quality presets |
|
||||
| `signaling-contracts.ts` | `SignalingMessage`, `SignalingMessageType` |
|
||||
| `attachment-contracts.ts` | `ChatAttachmentAnnouncement`, `ChatAttachmentMeta` |
|
||||
|
||||
## When to add here vs. in a domain
|
||||
|
||||
Add to shared-kernel when a type is referenced by **two or more domains** or by
|
||||
**infrastructure + store**. If a type is only used inside one domain, keep it
|
||||
in that domain's `domain/` folder.
|
||||
|
||||
## Backward compatibility
|
||||
|
||||
`core/models/index.ts` re-exports everything from this folder so existing
|
||||
`import { X } from 'core/models'` lines keep working. **New code** should
|
||||
import directly from `shared-kernel/` for clarity.
|
||||
14
toju-app/src/app/shared-kernel/attachment-contracts.ts
Normal file
14
toju-app/src/app/shared-kernel/attachment-contracts.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export interface ChatAttachmentAnnouncement {
|
||||
id: string;
|
||||
filename: string;
|
||||
size: number;
|
||||
mime: string;
|
||||
isImage: boolean;
|
||||
uploaderPeerId?: string;
|
||||
}
|
||||
|
||||
export interface ChatAttachmentMeta extends ChatAttachmentAnnouncement {
|
||||
messageId: string;
|
||||
filePath?: string;
|
||||
savedPath?: string;
|
||||
}
|
||||
347
toju-app/src/app/shared-kernel/chat-events.ts
Normal file
347
toju-app/src/app/shared-kernel/chat-events.ts
Normal file
@@ -0,0 +1,347 @@
|
||||
import type { Message, Reaction } from './message.models';
|
||||
import type { UserRole, RoomMember } from './user.models';
|
||||
import type {
|
||||
Room,
|
||||
RoomSettings,
|
||||
RoomPermissions,
|
||||
Channel
|
||||
} from './room.models';
|
||||
import type { VoiceState } from './voice-state.models';
|
||||
import type { BanEntry } from './moderation.models';
|
||||
import type { ChatAttachmentAnnouncement, ChatAttachmentMeta } from './attachment-contracts';
|
||||
|
||||
export interface ChatInventoryItem {
|
||||
id: string;
|
||||
ts: number;
|
||||
rc: number;
|
||||
ac?: number;
|
||||
}
|
||||
|
||||
// Every field that appears on any event is kept optional here so that
|
||||
// code which accesses `event.roomId` etc. without narrowing first
|
||||
// still compiles. Individual event interfaces below then make the
|
||||
// relevant fields **required**.
|
||||
|
||||
export interface ChatEventBase {
|
||||
fromPeerId?: string;
|
||||
messageId?: string;
|
||||
message?: Message;
|
||||
reaction?: Reaction;
|
||||
data?: string | Partial<Message>;
|
||||
timestamp?: number;
|
||||
targetUserId?: string;
|
||||
roomId?: string;
|
||||
items?: ChatInventoryItem[];
|
||||
ids?: string[];
|
||||
messages?: Message[];
|
||||
attachments?: Record<string, ChatAttachmentMeta[]>;
|
||||
total?: number;
|
||||
index?: number;
|
||||
count?: number;
|
||||
lastUpdated?: number;
|
||||
file?: ChatAttachmentAnnouncement;
|
||||
fileId?: string;
|
||||
hostId?: string;
|
||||
hostOderId?: string;
|
||||
previousHostId?: string;
|
||||
previousHostOderId?: string;
|
||||
kickedBy?: string;
|
||||
bannedBy?: string;
|
||||
content?: string;
|
||||
editedAt?: number;
|
||||
deletedAt?: number;
|
||||
deletedBy?: string;
|
||||
oderId?: string;
|
||||
displayName?: string;
|
||||
emoji?: string;
|
||||
reason?: string;
|
||||
settings?: Partial<RoomSettings>;
|
||||
permissions?: Partial<RoomPermissions>;
|
||||
voiceState?: Partial<VoiceState>;
|
||||
isScreenSharing?: boolean;
|
||||
icon?: string;
|
||||
iconUpdatedAt?: number;
|
||||
role?: UserRole;
|
||||
room?: Partial<Room>;
|
||||
channels?: Channel[];
|
||||
members?: RoomMember[];
|
||||
ban?: BanEntry;
|
||||
bans?: BanEntry[];
|
||||
banOderId?: string;
|
||||
expiresAt?: number;
|
||||
}
|
||||
|
||||
export interface ChatMessageEvent extends ChatEventBase {
|
||||
type: 'message' | 'chat-message';
|
||||
message: Message;
|
||||
}
|
||||
|
||||
export interface MessageEditedEvent extends ChatEventBase {
|
||||
type: 'edit' | 'message-edited';
|
||||
messageId: string;
|
||||
content: string;
|
||||
editedAt: number;
|
||||
}
|
||||
|
||||
export interface MessageDeletedEvent extends ChatEventBase {
|
||||
type: 'delete' | 'message-deleted';
|
||||
messageId: string;
|
||||
}
|
||||
|
||||
export interface ReactionAddedEvent extends ChatEventBase {
|
||||
type: 'reaction' | 'reaction-added';
|
||||
messageId: string;
|
||||
reaction: Reaction;
|
||||
}
|
||||
|
||||
export interface ReactionRemovedEvent extends ChatEventBase {
|
||||
type: 'reaction-removed';
|
||||
messageId: string;
|
||||
oderId: string;
|
||||
emoji: string;
|
||||
}
|
||||
|
||||
export interface FileAnnounceChatEvent extends ChatEventBase {
|
||||
type: 'file-announce';
|
||||
messageId: string;
|
||||
file: ChatAttachmentAnnouncement;
|
||||
}
|
||||
|
||||
export interface FileChunkChatEvent extends ChatEventBase {
|
||||
type: 'file-chunk';
|
||||
messageId: string;
|
||||
fileId: string;
|
||||
index: number;
|
||||
total: number;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface FileRequestChatEvent extends ChatEventBase {
|
||||
type: 'file-request';
|
||||
messageId: string;
|
||||
fileId: string;
|
||||
}
|
||||
|
||||
export interface FileCancelChatEvent extends ChatEventBase {
|
||||
type: 'file-cancel';
|
||||
messageId: string;
|
||||
fileId: string;
|
||||
}
|
||||
|
||||
export interface FileNotFoundChatEvent extends ChatEventBase {
|
||||
type: 'file-not-found';
|
||||
messageId: string;
|
||||
fileId: string;
|
||||
}
|
||||
|
||||
export interface ChatInventoryRequestEvent extends ChatEventBase {
|
||||
type: 'chat-inventory-request';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface ChatInventoryEvent extends ChatEventBase {
|
||||
type: 'chat-inventory';
|
||||
roomId: string;
|
||||
items: ChatInventoryItem[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface ChatSyncRequestIdsEvent extends ChatEventBase {
|
||||
type: 'chat-sync-request-ids';
|
||||
roomId: string;
|
||||
ids: string[];
|
||||
}
|
||||
|
||||
export interface ChatSyncBatchEvent extends ChatEventBase {
|
||||
type: 'chat-sync-batch';
|
||||
roomId: string;
|
||||
messages: Message[];
|
||||
}
|
||||
|
||||
export interface ChatSyncSummaryEvent extends ChatEventBase {
|
||||
type: 'chat-sync-summary';
|
||||
}
|
||||
|
||||
export interface ChatSyncRequestEvent extends ChatEventBase {
|
||||
type: 'chat-sync-request';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface ChatSyncFullEvent extends ChatEventBase {
|
||||
type: 'chat-sync-full';
|
||||
roomId: string;
|
||||
messages: Message[];
|
||||
}
|
||||
|
||||
export interface RoomDeletedEvent extends ChatEventBase {
|
||||
type: 'room-deleted';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface RoomSettingsUpdateEvent extends ChatEventBase {
|
||||
type: 'room-settings-update';
|
||||
roomId: string;
|
||||
settings: Partial<RoomSettings>;
|
||||
}
|
||||
|
||||
export interface RoomPermissionsUpdateEvent extends ChatEventBase {
|
||||
type: 'room-permissions-update';
|
||||
roomId: string;
|
||||
permissions?: Partial<RoomPermissions>;
|
||||
}
|
||||
|
||||
export interface HostChangeEvent extends ChatEventBase {
|
||||
type: 'host-change';
|
||||
roomId: string;
|
||||
hostId: string;
|
||||
hostOderId: string;
|
||||
previousHostId: string;
|
||||
previousHostOderId: string;
|
||||
}
|
||||
|
||||
export interface VoiceStateEvent extends ChatEventBase {
|
||||
type: 'voice-state';
|
||||
voiceState: Partial<VoiceState>;
|
||||
}
|
||||
|
||||
export interface ScreenStateEvent extends ChatEventBase {
|
||||
type: 'screen-state';
|
||||
isScreenSharing: boolean;
|
||||
}
|
||||
|
||||
export interface VoiceStateRequestEvent extends ChatEventBase {
|
||||
type: 'voice-state-request';
|
||||
}
|
||||
|
||||
export interface StateRequestEvent extends ChatEventBase {
|
||||
type: 'state-request';
|
||||
}
|
||||
|
||||
export interface ScreenShareRequestEvent extends ChatEventBase {
|
||||
type: 'screen-share-request';
|
||||
}
|
||||
|
||||
export interface ScreenShareStopEvent extends ChatEventBase {
|
||||
type: 'screen-share-stop';
|
||||
}
|
||||
|
||||
export interface ServerIconSummaryEvent extends ChatEventBase {
|
||||
type: 'server-icon-summary';
|
||||
roomId: string;
|
||||
iconUpdatedAt: number;
|
||||
}
|
||||
|
||||
export interface ServerIconRequestEvent extends ChatEventBase {
|
||||
type: 'server-icon-request';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface ServerIconFullEvent extends ChatEventBase {
|
||||
type: 'server-icon-full';
|
||||
roomId: string;
|
||||
icon?: string;
|
||||
iconUpdatedAt: number;
|
||||
}
|
||||
|
||||
export interface ServerIconUpdateEvent extends ChatEventBase {
|
||||
type: 'server-icon-update';
|
||||
roomId: string;
|
||||
icon: string;
|
||||
iconUpdatedAt: number;
|
||||
}
|
||||
|
||||
export interface ServerStateRequestEvent extends ChatEventBase {
|
||||
type: 'server-state-request';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface ServerStateFullEvent extends ChatEventBase {
|
||||
type: 'server-state-full';
|
||||
roomId: string;
|
||||
room: Partial<Room>;
|
||||
}
|
||||
|
||||
export interface MemberRosterRequestEvent extends ChatEventBase {
|
||||
type: 'member-roster-request';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface MemberRosterEvent extends ChatEventBase {
|
||||
type: 'member-roster';
|
||||
roomId: string;
|
||||
members: RoomMember[];
|
||||
}
|
||||
|
||||
export interface MemberLeaveEvent extends ChatEventBase {
|
||||
type: 'member-leave';
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export interface RoleChangeEvent extends ChatEventBase {
|
||||
type: 'role-change';
|
||||
}
|
||||
|
||||
export interface KickEvent extends ChatEventBase {
|
||||
type: 'kick';
|
||||
}
|
||||
|
||||
export interface BanEvent extends ChatEventBase {
|
||||
type: 'ban';
|
||||
}
|
||||
|
||||
export interface UnbanEvent extends ChatEventBase {
|
||||
type: 'unban';
|
||||
}
|
||||
|
||||
export interface ChannelsUpdateEvent extends ChatEventBase {
|
||||
type: 'channels-update';
|
||||
roomId: string;
|
||||
channels: Channel[];
|
||||
}
|
||||
|
||||
/** Discriminated union of all P2P chat events. Narrow via `event.type`. */
|
||||
export type ChatEvent =
|
||||
| ChatMessageEvent
|
||||
| MessageEditedEvent
|
||||
| MessageDeletedEvent
|
||||
| ReactionAddedEvent
|
||||
| ReactionRemovedEvent
|
||||
| FileAnnounceChatEvent
|
||||
| FileChunkChatEvent
|
||||
| FileRequestChatEvent
|
||||
| FileCancelChatEvent
|
||||
| FileNotFoundChatEvent
|
||||
| ChatInventoryRequestEvent
|
||||
| ChatInventoryEvent
|
||||
| ChatSyncRequestIdsEvent
|
||||
| ChatSyncBatchEvent
|
||||
| ChatSyncSummaryEvent
|
||||
| ChatSyncRequestEvent
|
||||
| ChatSyncFullEvent
|
||||
| RoomDeletedEvent
|
||||
| RoomSettingsUpdateEvent
|
||||
| RoomPermissionsUpdateEvent
|
||||
| HostChangeEvent
|
||||
| VoiceStateEvent
|
||||
| ScreenStateEvent
|
||||
| VoiceStateRequestEvent
|
||||
| StateRequestEvent
|
||||
| ScreenShareRequestEvent
|
||||
| ScreenShareStopEvent
|
||||
| ServerIconSummaryEvent
|
||||
| ServerIconRequestEvent
|
||||
| ServerIconFullEvent
|
||||
| ServerIconUpdateEvent
|
||||
| ServerStateRequestEvent
|
||||
| ServerStateFullEvent
|
||||
| MemberRosterRequestEvent
|
||||
| MemberRosterEvent
|
||||
| MemberLeaveEvent
|
||||
| RoleChangeEvent
|
||||
| KickEvent
|
||||
| BanEvent
|
||||
| UnbanEvent
|
||||
| ChannelsUpdateEvent;
|
||||
|
||||
/** All possible `type` values, derived from the union. */
|
||||
export type ChatEventType = ChatEvent['type'];
|
||||
9
toju-app/src/app/shared-kernel/index.ts
Normal file
9
toju-app/src/app/shared-kernel/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export * from './user.models';
|
||||
export * from './room.models';
|
||||
export * from './message.models';
|
||||
export * from './moderation.models';
|
||||
export * from './voice-state.models';
|
||||
export * from './chat-events';
|
||||
export * from './media-preferences';
|
||||
export * from './signaling-contracts';
|
||||
export * from './attachment-contracts';
|
||||
98
toju-app/src/app/shared-kernel/media-preferences.ts
Normal file
98
toju-app/src/app/shared-kernel/media-preferences.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
export const LATENCY_PROFILES = [
|
||||
'low',
|
||||
'balanced',
|
||||
'high'
|
||||
] as const;
|
||||
|
||||
export type LatencyProfile = typeof LATENCY_PROFILES[number];
|
||||
|
||||
export const DEFAULT_LATENCY_PROFILE: LatencyProfile = 'balanced';
|
||||
|
||||
export const SCREEN_SHARE_QUALITIES = [
|
||||
'performance',
|
||||
'balanced',
|
||||
'high-fps',
|
||||
'quality'
|
||||
] as const;
|
||||
|
||||
export type ScreenShareQuality = typeof SCREEN_SHARE_QUALITIES[number];
|
||||
|
||||
export const DEFAULT_SCREEN_SHARE_QUALITY: ScreenShareQuality = 'balanced';
|
||||
|
||||
export interface ScreenShareStartOptions {
|
||||
includeSystemAudio: boolean;
|
||||
quality: ScreenShareQuality;
|
||||
}
|
||||
|
||||
export interface ScreenShareQualityPreset {
|
||||
label: string;
|
||||
description: string;
|
||||
width: number;
|
||||
height: number;
|
||||
frameRate: number;
|
||||
maxBitrateBps: number;
|
||||
contentHint: 'motion' | 'detail';
|
||||
degradationPreference: 'maintain-framerate' | 'maintain-resolution';
|
||||
scaleResolutionDownBy?: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_SCREEN_SHARE_START_OPTIONS: ScreenShareStartOptions = {
|
||||
includeSystemAudio: false,
|
||||
quality: DEFAULT_SCREEN_SHARE_QUALITY
|
||||
};
|
||||
|
||||
export const SCREEN_SHARE_QUALITY_PRESETS: Record<ScreenShareQuality, ScreenShareQualityPreset> = {
|
||||
performance: {
|
||||
label: 'Performance saver',
|
||||
description: '720p / 30 FPS with lower CPU and bandwidth usage.',
|
||||
width: 1280,
|
||||
height: 720,
|
||||
frameRate: 30,
|
||||
maxBitrateBps: 2_000_000,
|
||||
contentHint: 'motion',
|
||||
degradationPreference: 'maintain-framerate',
|
||||
scaleResolutionDownBy: 1
|
||||
},
|
||||
balanced: {
|
||||
label: 'Balanced',
|
||||
description: '1080p / 30 FPS for stable quality in most cases.',
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
frameRate: 30,
|
||||
maxBitrateBps: 4_000_000,
|
||||
contentHint: 'detail',
|
||||
degradationPreference: 'maintain-resolution',
|
||||
scaleResolutionDownBy: 1
|
||||
},
|
||||
'high-fps': {
|
||||
label: 'High FPS',
|
||||
description: '1080p / 60 FPS for games and fast motion.',
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
frameRate: 60,
|
||||
maxBitrateBps: 6_000_000,
|
||||
contentHint: 'motion',
|
||||
degradationPreference: 'maintain-framerate',
|
||||
scaleResolutionDownBy: 1
|
||||
},
|
||||
quality: {
|
||||
label: 'Sharp text',
|
||||
description: '1440p / 30 FPS for detailed UI and text clarity.',
|
||||
width: 2560,
|
||||
height: 1440,
|
||||
frameRate: 30,
|
||||
maxBitrateBps: 8_000_000,
|
||||
contentHint: 'detail',
|
||||
degradationPreference: 'maintain-resolution',
|
||||
scaleResolutionDownBy: 1
|
||||
}
|
||||
};
|
||||
|
||||
export const SCREEN_SHARE_QUALITY_OPTIONS = (
|
||||
Object.entries(SCREEN_SHARE_QUALITY_PRESETS) as [ScreenShareQuality, ScreenShareQualityPreset][]
|
||||
).map(([id, preset]) => ({
|
||||
id,
|
||||
...preset
|
||||
}));
|
||||
|
||||
export const ELECTRON_ENTIRE_SCREEN_SOURCE_NAME = 'Entire Screen';
|
||||
24
toju-app/src/app/shared-kernel/message.models.ts
Normal file
24
toju-app/src/app/shared-kernel/message.models.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export const DELETED_MESSAGE_CONTENT = '[Message deleted]';
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
roomId: string;
|
||||
channelId?: string;
|
||||
senderId: string;
|
||||
senderName: string;
|
||||
content: string;
|
||||
timestamp: number;
|
||||
editedAt?: number;
|
||||
reactions: Reaction[];
|
||||
isDeleted: boolean;
|
||||
replyToId?: string;
|
||||
}
|
||||
|
||||
export interface Reaction {
|
||||
id: string;
|
||||
messageId: string;
|
||||
oderId: string;
|
||||
userId: string;
|
||||
emoji: string;
|
||||
timestamp: number;
|
||||
}
|
||||
10
toju-app/src/app/shared-kernel/moderation.models.ts
Normal file
10
toju-app/src/app/shared-kernel/moderation.models.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export interface BanEntry {
|
||||
oderId: string;
|
||||
userId: string;
|
||||
roomId: string;
|
||||
bannedBy: string;
|
||||
displayName?: string;
|
||||
reason?: string;
|
||||
expiresAt?: number;
|
||||
timestamp: number;
|
||||
}
|
||||
54
toju-app/src/app/shared-kernel/room.models.ts
Normal file
54
toju-app/src/app/shared-kernel/room.models.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import type { RoomMember } from './user.models';
|
||||
|
||||
export type ChannelType = 'text' | 'voice';
|
||||
|
||||
export interface Channel {
|
||||
id: string;
|
||||
name: string;
|
||||
type: ChannelType;
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface Room {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
topic?: string;
|
||||
hostId: string;
|
||||
password?: string;
|
||||
hasPassword?: boolean;
|
||||
isPrivate: boolean;
|
||||
createdAt: number;
|
||||
userCount: number;
|
||||
maxUsers?: number;
|
||||
icon?: string;
|
||||
iconUpdatedAt?: number;
|
||||
permissions?: RoomPermissions;
|
||||
channels?: Channel[];
|
||||
members?: RoomMember[];
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
sourceUrl?: string;
|
||||
}
|
||||
|
||||
export interface RoomSettings {
|
||||
name: string;
|
||||
description?: string;
|
||||
topic?: string;
|
||||
isPrivate: boolean;
|
||||
password?: string;
|
||||
hasPassword?: boolean;
|
||||
maxUsers?: number;
|
||||
rules?: string[];
|
||||
}
|
||||
|
||||
export interface RoomPermissions {
|
||||
adminsManageRooms?: boolean;
|
||||
moderatorsManageRooms?: boolean;
|
||||
adminsManageIcon?: boolean;
|
||||
moderatorsManageIcon?: boolean;
|
||||
allowVoice?: boolean;
|
||||
allowScreenShare?: boolean;
|
||||
allowFileUploads?: boolean;
|
||||
slowModeInterval?: number;
|
||||
}
|
||||
20
toju-app/src/app/shared-kernel/signaling-contracts.ts
Normal file
20
toju-app/src/app/shared-kernel/signaling-contracts.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export type SignalingMessageType =
|
||||
| 'offer'
|
||||
| 'answer'
|
||||
| 'ice-candidate'
|
||||
| 'join'
|
||||
| 'leave'
|
||||
| 'chat'
|
||||
| 'state-sync'
|
||||
| 'kick'
|
||||
| 'ban'
|
||||
| 'host-change'
|
||||
| 'room-update';
|
||||
|
||||
export interface SignalingMessage {
|
||||
type: SignalingMessageType;
|
||||
from: string;
|
||||
to?: string;
|
||||
payload: unknown;
|
||||
timestamp: number;
|
||||
}
|
||||
33
toju-app/src/app/shared-kernel/user.models.ts
Normal file
33
toju-app/src/app/shared-kernel/user.models.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { VoiceState, ScreenShareState } from './voice-state.models';
|
||||
|
||||
export type UserStatus = 'online' | 'away' | 'busy' | 'offline';
|
||||
|
||||
export type UserRole = 'host' | 'admin' | 'moderator' | 'member';
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
oderId: string;
|
||||
username: string;
|
||||
displayName: string;
|
||||
avatarUrl?: string;
|
||||
status: UserStatus;
|
||||
role: UserRole;
|
||||
joinedAt: number;
|
||||
peerId?: string;
|
||||
isOnline?: boolean;
|
||||
isAdmin?: boolean;
|
||||
isRoomOwner?: boolean;
|
||||
voiceState?: VoiceState;
|
||||
screenShareState?: ScreenShareState;
|
||||
}
|
||||
|
||||
export interface RoomMember {
|
||||
id: string;
|
||||
oderId?: string;
|
||||
username: string;
|
||||
displayName: string;
|
||||
avatarUrl?: string;
|
||||
role: UserRole;
|
||||
joinedAt: number;
|
||||
lastSeenAt: number;
|
||||
}
|
||||
17
toju-app/src/app/shared-kernel/voice-state.models.ts
Normal file
17
toju-app/src/app/shared-kernel/voice-state.models.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export interface VoiceState {
|
||||
isConnected: boolean;
|
||||
isMuted: boolean;
|
||||
isDeafened: boolean;
|
||||
isSpeaking: boolean;
|
||||
isMutedByAdmin?: boolean;
|
||||
volume?: number;
|
||||
roomId?: string;
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
export interface ScreenShareState {
|
||||
isSharing: boolean;
|
||||
streamId?: string;
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user