looood / src /types.ts
looda3131's picture
Clean push without any binary history
cc276cc
import type { JsonWebKey } from 'crypto';
import type { IAgoraRTCClient, ICameraVideoTrack, IMicrophoneAudioTrack, IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng';
import { z } from 'zod';
export type Language = 'en' | 'ar';
export type VideoQuality = 'low' | 'medium' | 'high';
export type AppTheme = 'light' | 'dark' | 'theme-neon-nights' | 'theme-desert-oasis' | 'theme-kyoto-garden';
export interface UserProfile {
uid: string;
displayName: string;
photoURL: string;
publicId: string;
bio?: string;
status?: string;
publicKey?: JsonWebKey;
blockedUsers?: { [uid: string]: true };
blockedBy?: { [uid: string]: true };
fcmToken?: string;
privacySettings?: PrivacySettings;
}
export interface User extends UserProfile {
isOnline?: boolean;
lastSeen?: number | object;
}
export interface ChatRecipient extends User {
isGroup?: boolean;
isBot?: boolean;
}
export interface Contact {
uid: string;
name: string;
addedAt: number;
photoURL?: string;
publicId: string;
publicKey?: JsonWebKey;
isOnline?: boolean;
}
export type GroupType = 'general' | 'study' | 'friends' | 'gaming';
export type GroupSendingMode = 'everyone' | 'admins' | 'owner';
export interface Group {
id: string;
info: {
name: string;
photoURL: string;
createdBy: string;
createdAt: number;
description?: string;
type: GroupType;
settings?: {
sendingMode?: GroupSendingMode;
};
mutedMembers?: { [uid: string]: true };
};
members: { [uid: string]: true };
admins: { [uid: string]: true };
encryptedKeys: { [uid: string]: string };
keyLastRotatedAt?: number;
}
export interface GroupMember extends User {
isAdmin: boolean;
isMuted?: boolean;
}
export interface GroupInvitation {
groupId: string;
groupName: string;
groupPhotoURL: string;
invitedBy: string;
}
export interface ChatRequest {
fromUid: string;
displayName: string;
photoURL: string;
publicId: string;
timestamp: number;
}
export interface ReplyTo {
id: string;
text: string;
displayName: string;
imageKey?: string;
videoKey?: string;
audioKey?: string;
}
export interface URLPreviewData {
url: string;
title: string;
description?: string;
imageUrl?: string;
domain: string;
}
export interface EncryptedMessage {
iv: number[];
ciphertext: number[];
}
export interface ActionPayload {
type: string;
}
export interface Message {
id: string;
text?: string | null;
encryptedText?: string | null;
compressedText?: string; // For ultra saving mode
originalSize?: number; // Size before compression
compressedSize?: number; // Size after compression
timestamp: number;
editedAt?: number;
reactions?: { [key: string]: { [uid: string]: { displayName: string } } };
audioKey?: string;
audioDuration?: number;
transcription?: string;
imageKey?: string;
videoKey?: string;
fileKey?: string;
fileName?: string;
fileSize?: number;
fileType?: string;
encryptionKey?: { [uid: string]: string } | { group: string }; // Key to decrypt media files, per user OR for group
keyVersion?: number; // Timestamp of the group key used for this message
urlPreviewData?: URLPreviewData;
isDeleted?: boolean;
isSystemMessage?: boolean;
status?: 'sent' | 'pending' | 'failed';
uploadProgress?: number; // For optimistic UI on uploads
replyTo?: ReplyTo | null;
sender: string;
senderDisplayName: string;
senderPhotoUrl: string;
isSender?: boolean;
deliveredTo?: { [uid: string]: number };
readBy?: { [uid:string]: number };
detectedLang?: string;
action?: ActionPayload;
}
export interface ChatInfo {
type: 'private' | 'group' | 'public';
participants: { [uid: string]: true | { lastRead: number } };
status?: 'accepted' | 'blocked';
initiator?: string;
}
export interface Reaction {
emoji: string;
users: string[];
}
export type DataMode = 'normal' | 'ultra';
export type FontStyle = 'default' | 'casual';
export interface AIUser {
id:string;
name: string;
avatarUrl: string;
}
export enum PostCategory {
Funny = 'funny',
Sad = 'sad',
Deep = 'deep',
Angry = 'angry',
Inspirational = 'inspirational',
General = 'general'
}
export interface LiveReaction {
id: string;
emoji: string;
}
export interface AIComment {
id: string;
author: AIUser;
text: string;
reactions: { [key: string]: number };
uiState: {
userReaction: string | null;
liveReactions: LiveReaction[];
};
}
export interface AIPost {
id: string;
author: AIUser;
content: string;
imageUrl: string;
imageQuery: string;
isMeme: boolean;
reactions: { [key: string]: number };
comments: AIComment[];
createdAt: string;
category: PostCategory;
}
export type PostWithUIState = AIPost & {
uiState: {
userReaction: string | null; // e.g., 'heart', 'laugh', null
showCommentInput: boolean;
isGeneratingComment: boolean;
hasGeneratedBulkComments: boolean;
liveReactions: LiveReaction[];
};
};
// For Group Chat
export interface Persona {
name: string;
avatarUrl: string;
}
export interface GroupChatMessage {
personaName: string;
message: string;
}
export interface PrivacySettings {
showOnline: boolean;
showTyping: boolean;
readReceipts: boolean;
whoCanAdd: 'everyone' | 'contacts';
whoCanViewProfile: 'everyone' | 'contacts';
}
// --- WebRTC Call Types ---
export type CallType = 'audio' | 'video';
export interface CallState {
status: 'idle' | 'outgoing' | 'incoming' | 'connected' | 'connecting';
peer: UserProfile | null;
type: CallType | null;
channelName: string | null;
isMuted: boolean;
isVideoOff: boolean;
startTime: number | null;
}
export interface CallSignal {
offer?: boolean;
answer?: boolean;
caller?: UserProfile;
type?: CallType;
channelName?: string;
iceCandidate?: any;
connected?: boolean;
ended?: boolean;
rejected?: boolean;
}
export interface PresenceStatus {
isOnline: boolean;
lastSeen: number;
isBusy?: boolean;
}
// AI Schemas for Genkit
export const GenerateImageInputSchema = z.object({
prompt: z.string().describe('A descriptive prompt for the image generation model.'),
});
export type GenerateImageInput = z.infer<typeof GenerateImageInputSchema>;
export const GenerateImageOutputSchema = z.object({
imageUrl: z.string().describe('The data URI of the generated image.'),
});
export type GenerateImageOutput = z.infer<typeof GenerateImageOutputSchema>;
export interface LocalAiAction {
type: string;
keywords: {
en: string[];
ar: string[];
};
response: {
en: string;
ar: string;
};
}
export const MessageSchema = z.object({
role: z.enum(['user', 'model']),
content: z.array(z.object({ text: z.string() })),
});
export type Message = z.infer<typeof MessageSchema>;