Files
Toju/src/app/core/models/index.ts

422 lines
12 KiB
TypeScript

/**
* Core domain models for the MetoYou P2P chat application.
*
* These interfaces define the data structures shared across
* services, store, and components.
*/
/** Possible online-presence statuses for a user. */
export type UserStatus = 'online' | 'away' | 'busy' | 'offline';
/** Role hierarchy within a room/server. */
export type UserRole = 'host' | 'admin' | 'moderator' | 'member';
/** Channel type within a server. */
export type ChannelType = 'text' | 'voice';
/**
* Represents an authenticated user in the system.
* Users are identified by both a local `id` and a network-wide `oderId`.
*/
export interface User {
/** Local database identifier. */
id: string;
/** Network-wide unique identifier used for peer identification. */
oderId: string;
/** Login username (unique per auth server). */
username: string;
/** Human-readable display name shown in the UI. */
displayName: string;
/** Optional URL to the user's avatar image. */
avatarUrl?: string;
/** Current online-presence status. */
status: UserStatus;
/** Role within the current room/server. */
role: UserRole;
/** Epoch timestamp (ms) when the user first joined. */
joinedAt: number;
/** WebRTC peer identifier (transient, set when connected). */
peerId?: string;
/** Whether the user is currently connected. */
isOnline?: boolean;
/** Whether the user holds admin-level privileges. */
isAdmin?: boolean;
/** Whether the user is the owner of the current room. */
isRoomOwner?: boolean;
/** Real-time voice connection state. */
voiceState?: VoiceState;
/** Real-time screen-sharing state. */
screenShareState?: ScreenShareState;
}
/**
* A communication channel within a server (either text or voice).
*/
export interface Channel {
/** Unique channel identifier. */
id: string;
/** Display name of the channel. */
name: string;
/** Whether this is a text chat or voice channel. */
type: ChannelType;
/** Sort order within its type group (lower value = higher priority). */
position: number;
}
/**
* A single chat message in a room's text channel.
*/
export interface Message {
/** Unique message identifier. */
id: string;
/** The room this message belongs to. */
roomId: string;
/** The text channel within the room (defaults to 'general'). */
channelId?: string;
/** Identifier of the user who sent the message. */
senderId: string;
/** Display name of the sender at the time of sending. */
senderName: string;
/** Markdown-formatted message body. */
content: string;
/** Epoch timestamp (ms) when the message was created. */
timestamp: number;
/** Epoch timestamp (ms) of the last edit, if any. */
editedAt?: number;
/** Emoji reactions attached to this message. */
reactions: Reaction[];
/** Whether this message has been soft-deleted. */
isDeleted: boolean;
/** If this is a reply, the ID of the parent message. */
replyToId?: string;
}
/**
* An emoji reaction on a message.
*/
export interface Reaction {
/** Unique reaction identifier. */
id: string;
/** The message this reaction is attached to. */
messageId: string;
/** Network-wide user ID of the reactor. */
oderId: string;
/** Alias for `oderId` (kept for backward compatibility). */
userId: string;
/** The emoji character(s) used. */
emoji: string;
/** Epoch timestamp (ms) when the reaction was added. */
timestamp: number;
}
/**
* A chat room (server) that users can join to communicate.
*/
export interface Room {
/** Unique room identifier. */
id: string;
/** Display name of the room. */
name: string;
/** Optional long-form description. */
description?: string;
/** Short topic/status line shown in the header. */
topic?: string;
/** User ID of the room's creator/owner. */
hostId: string;
/** Password required to join (if private). */
password?: string;
/** Whether the room requires a password to join. */
isPrivate: boolean;
/** Epoch timestamp (ms) when the room was created. */
createdAt: number;
/** Current number of connected users. */
userCount: number;
/** Maximum allowed concurrent users. */
maxUsers?: number;
/** Server icon as a data-URL or remote URL. */
icon?: string;
/** Epoch timestamp (ms) of the last icon update (for conflict resolution). */
iconUpdatedAt?: number;
/** Role-based management permission overrides. */
permissions?: RoomPermissions;
/** Text and voice channels within the server. */
channels?: Channel[];
}
/**
* Editable subset of room properties exposed in the settings UI.
*/
export interface RoomSettings {
/** Room display name. */
name: string;
/** Optional long-form description. */
description?: string;
/** Short topic/status line. */
topic?: string;
/** Whether a password is required to join. */
isPrivate: boolean;
/** Password for private rooms. */
password?: string;
/** Maximum allowed concurrent users. */
maxUsers?: number;
/** Optional list of room rules. */
rules?: string[];
}
/**
* Fine-grained permission toggles for a room.
* Controls which roles can perform management actions.
*/
export interface RoomPermissions {
/** Whether admins can create/modify rooms. */
adminsManageRooms?: boolean;
/** Whether moderators can create/modify rooms. */
moderatorsManageRooms?: boolean;
/** Whether admins can change the server icon. */
adminsManageIcon?: boolean;
/** Whether moderators can change the server icon. */
moderatorsManageIcon?: boolean;
/** Whether voice channels are enabled. */
allowVoice?: boolean;
/** Whether screen sharing is enabled. */
allowScreenShare?: boolean;
/** Whether file uploads are enabled. */
allowFileUploads?: boolean;
/** Minimum delay (seconds) between messages (0 = disabled). */
slowModeInterval?: number;
}
/**
* A record of a user being banned from a room.
*/
export interface BanEntry {
/** Unique ban identifier (also used as the banned user's oderId). */
oderId: string;
/** The banned user's local ID. */
userId: string;
/** The room the ban applies to. */
roomId: string;
/** User ID of the admin who issued the ban. */
bannedBy: string;
/** Display name of the banned user at the time of banning. */
displayName?: string;
/** Human-readable reason for the ban. */
reason?: string;
/** Epoch timestamp (ms) when the ban expires (undefined = permanent). */
expiresAt?: number;
/** Epoch timestamp (ms) when the ban was issued. */
timestamp: number;
}
/**
* Tracks the state of a WebRTC peer connection.
*/
export interface PeerConnection {
/** Remote peer identifier. */
peerId: string;
/** Local user identifier. */
userId: string;
/** Current connection lifecycle state. */
status: 'connecting' | 'connected' | 'disconnected' | 'failed';
/** The RTCDataChannel used for P2P messaging. */
dataChannel?: RTCDataChannel;
/** The underlying RTCPeerConnection. */
connection?: RTCPeerConnection;
}
/**
* Real-time voice connection state for a user in a voice channel.
*/
export interface VoiceState {
/** Whether the user is connected to a voice channel. */
isConnected: boolean;
/** Whether the user's microphone is muted (self or by admin). */
isMuted: boolean;
/** Whether the user has deafened themselves. */
isDeafened: boolean;
/** Whether the user is currently speaking (voice activity detection). */
isSpeaking: boolean;
/** Whether the user was server-muted by an admin. */
isMutedByAdmin?: boolean;
/** User's output volume level (0-1). */
volume?: number;
/** The voice channel ID within the server (e.g. 'vc-general'). */
roomId?: string;
/** The server ID the user is connected to voice in. */
serverId?: string;
}
/**
* Real-time screen-sharing state for a user.
*/
export interface ScreenShareState {
/** Whether the user is actively sharing their screen. */
isSharing: boolean;
/** MediaStream ID of the screen capture. */
streamId?: string;
/** Desktop capturer source ID (Electron only). */
sourceId?: string;
/** Human-readable name of the captured source. */
sourceName?: string;
}
/** All signaling message types exchanged via the WebSocket relay. */
export type SignalingMessageType =
| 'offer'
| 'answer'
| 'ice-candidate'
| 'join'
| 'leave'
| 'chat'
| 'state-sync'
| 'kick'
| 'ban'
| 'host-change'
| 'room-update';
/**
* A message exchanged via the signaling WebSocket server.
*/
export interface SignalingMessage {
/** The type of signaling event. */
type: SignalingMessageType;
/** Sender's peer ID. */
from: string;
/** Optional target peer ID (for directed messages). */
to?: string;
/** Arbitrary payload specific to the message type. */
payload: unknown;
/** Epoch timestamp (ms) when the message was sent. */
timestamp: number;
}
/** All P2P chat event types exchanged via RTCDataChannel. */
export type ChatEventType =
| 'message'
| 'chat-message'
| 'edit'
| 'message-edited'
| 'delete'
| 'message-deleted'
| 'reaction'
| 'reaction-added'
| 'reaction-removed'
| 'kick'
| 'ban'
| 'room-deleted'
| 'room-settings-update'
| 'voice-state'
| 'chat-inventory-request'
| 'voice-state-request'
| 'state-request'
| 'screen-state'
| 'role-change'
| 'channels-update';
/**
* A P2P event exchanged between peers via RTCDataChannel.
* The `type` field determines which optional fields are populated.
*/
export interface ChatEvent {
/** The type of P2P event. */
type: ChatEventType;
/** Relevant message ID (for edits, deletes, reactions). */
messageId?: string;
/** Full message payload (for new messages). */
message?: Message;
/** Reaction payload (for reaction events). */
reaction?: Reaction;
/** Partial message updates (for edits). */
data?: Partial<Message>;
/** Event timestamp. */
timestamp?: number;
/** Target user ID (for kick/ban). */
targetUserId?: string;
/** Room ID the event pertains to. */
roomId?: string;
/** User who issued a kick. */
kickedBy?: string;
/** User who issued a ban. */
bannedBy?: string;
/** Text content (for messages/edits). */
content?: string;
/** Edit timestamp. */
editedAt?: number;
/** User who performed a delete. */
deletedBy?: string;
/** Network-wide user identifier. */
oderId?: string;
/** Display name of the event sender. */
displayName?: string;
/** Emoji character (for reactions). */
emoji?: string;
/** Ban/kick reason. */
reason?: string;
/** Updated room settings. */
settings?: RoomSettings;
/** Partial voice state update. */
voiceState?: Partial<VoiceState>;
/** Screen-sharing flag. */
isScreenSharing?: boolean;
/** New role assignment. */
role?: UserRole;
/** Updated channel list. */
channels?: Channel[];
}
/**
* Server listing as returned by the directory API.
*/
export interface ServerInfo {
/** Unique server identifier. */
id: string;
/** Display name. */
name: string;
/** Optional description. */
description?: string;
/** Optional topic. */
topic?: string;
/** Display name of the host. */
hostName: string;
/** Owner's user ID. */
ownerId?: string;
/** Owner's public key / oderId. */
ownerPublicKey?: string;
/** Current number of connected users. */
userCount: number;
/** Maximum allowed users. */
maxUsers: number;
/** Whether a password is required. */
isPrivate: boolean;
/** Searchable tags. */
tags?: string[];
/** Epoch timestamp (ms) when the server was created. */
createdAt: number;
}
/**
* Request payload for joining a server.
*/
export interface JoinRequest {
/** Target room/server ID. */
roomId: string;
/** Requesting user's ID. */
userId: string;
/** Requesting user's username. */
username: string;
}
/**
* Top-level application state snapshot (used for diagnostics).
*/
export interface AppState {
/** The currently authenticated user, or null if logged out. */
currentUser: User | null;
/** The room the user is currently viewing, or null. */
currentRoom: Room | null;
/** Whether a connection attempt is in progress. */
isConnecting: boolean;
/** Last error message, or null. */
error: string | null;
}