├── public ├── robots.txt ├── banner.png ├── favicon.ico ├── sounds │ ├── new.mp3 │ └── typing.mp3 ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png └── site.webmanifest ├── tsconfig.node.tsbuildinfo ├── .vscode └── extensions.json ├── postcss.config.js ├── .prettierrc ├── tsconfig.json ├── .gitignore ├── vite.config.ts ├── src ├── vite-env.d.ts ├── lib │ ├── utils.ts │ ├── sound.ts │ ├── firebase.ts │ └── chat.ts ├── components │ ├── load-more-btn.tsx │ ├── ui │ │ ├── textarea.tsx │ │ ├── label.tsx │ │ ├── scroll-progress.tsx │ │ ├── input.tsx │ │ ├── animated-shiny-text.tsx │ │ ├── switch.tsx │ │ ├── avatar.tsx │ │ ├── scroll-area.tsx │ │ ├── rainbow-button.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── shine-border.tsx │ │ ├── dialog.tsx │ │ ├── animated-grid-pattern.tsx │ │ ├── alert-dialog.tsx │ │ ├── message-bubble.tsx │ │ ├── context-menu.tsx │ │ └── dropdown-menu.tsx │ ├── typing-bubble.tsx │ ├── logout-dialog.tsx │ ├── users-list.tsx │ ├── loader.tsx │ ├── message-input.tsx │ ├── chat-header.tsx │ ├── settings-dialog.tsx │ ├── profile-avatar.tsx │ └── chat-area.tsx ├── context │ ├── auth-context.tsx │ └── settings-context.tsx ├── hooks │ ├── useOnlineCount.ts │ ├── useOnlineUsers.ts │ ├── useTyping.ts │ ├── useSettings.ts │ ├── useChat.ts │ └── useAuth.ts ├── pages │ ├── chat.tsx │ └── home.tsx ├── types │ └── index.d.ts ├── main.tsx ├── App.tsx ├── index.css └── data │ └── country-data.ts ├── components.json ├── tsconfig.node.json ├── tsconfig.app.json ├── eslint.config.js ├── LICENSE ├── firebase.json ├── tsconfig.app.tsbuildinfo ├── .rules ├── package.json ├── index.html ├── README.md ├── tailwind.config.ts └── CONTRIBUTING.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * -------------------------------------------------------------------------------- /tsconfig.node.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"root":["./vite.config.ts"],"version":"5.6.3"} -------------------------------------------------------------------------------- /public/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/banner.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/sounds/new.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/sounds/new.mp3 -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chflick.firecode" 4 | ] 5 | } -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/sounds/typing.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/sounds/typing.mp3 -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devxprite/Chat-World/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "tabWidth": 4, 4 | "singleQuote": true, 5 | "arrowParens": "avoid", 6 | "experimentalTernaries": true 7 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.app.json" 6 | }, 7 | { 8 | "path": "./tsconfig.node.json" 9 | } 10 | ], 11 | "compilerOptions": { 12 | "baseUrl": ".", 13 | "paths": { 14 | "@/*": ["./src/*"] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .vercel 27 | pnpm-lock.yaml 28 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | //@ts-ignore 5 | import path from 'path'; 6 | 7 | //@ts-ignore 8 | const root = path.resolve(__dirname, 'src'); 9 | 10 | // https://vite.dev/config/ 11 | export default defineConfig({ 12 | plugins: [react()], 13 | resolve: { 14 | alias: { 15 | '@': path.resolve(__dirname, './src'), 16 | }, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | 4 | 5 | interface ImportMetaEnv { 6 | readonly VITE_FIREBASE_API_KEY: string; 7 | readonly VITE_FIREBASE_AUTH_DOMAIN: string; 8 | readonly VITE_FIREBASE_PROJECT_ID: string; 9 | readonly VITE_FIREBASE_STORAGE_BUCKET: string; 10 | readonly VITE_FIREBASE_MESSAGING_SENDER_ID: string; 11 | readonly VITE_FIREBASE_APP_ID: string; 12 | readonly VITE_IPINFO_TOKEN: string; 13 | } 14 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/index.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | } 20 | } -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { twMerge } from 'tailwind-merge'; 2 | import { clsx, type ClassValue } from 'clsx'; 3 | import { format, isToday, isYesterday, isThisWeek } from 'date-fns'; 4 | 5 | export function cn(...inputs: ClassValue[]) { 6 | return twMerge(clsx(inputs)); 7 | } 8 | 9 | export function formatDateCalendar(date: Date): string { 10 | if (isToday(date)) return 'Today'; 11 | else if (isYesterday(date)) return 'Yesterday'; 12 | else if (isThisWeek(date)) return format(date, 'eeee'); 13 | else return format(date, 'MMM d, yyyy'); 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": ["ES2023"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": true, 14 | 15 | /* Linting */ 16 | "strict": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["vite.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Chat World", 3 | "short_name": "Chat World", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#000000", 17 | "background_color": "#000000", 18 | "display": "standalone", 19 | "orientation": "portrait", 20 | "scope": "/", 21 | "start_url": "/" 22 | } -------------------------------------------------------------------------------- /src/components/load-more-btn.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import { RefreshCcw } from 'lucide-react'; 3 | 4 | const LoadMore = ({ onClick, isLoading }: { onClick?: () => void; isLoading: boolean }) => ( 5 | 16 | ); 17 | 18 | export default LoadMore; 19 | -------------------------------------------------------------------------------- /src/lib/sound.ts: -------------------------------------------------------------------------------- 1 | type SoundType = 'newMessage' | 'typing'; 2 | 3 | class SoundManager { 4 | private readonly sounds: Record; 5 | 6 | constructor() { 7 | this.sounds = { 8 | newMessage: new Audio('/sounds/new.mp3'), 9 | typing: new Audio('/sounds/typing.mp3'), 10 | }; 11 | 12 | this.sounds.newMessage.volume = 0.8; 13 | this.sounds.typing.volume = 0.6; 14 | } 15 | 16 | play(type: SoundType): void { 17 | this.sounds[type]?.play().catch(error => console.error(`Error playing ${type} sound:`, error)); 18 | } 19 | } 20 | 21 | export const soundManager = new SoundManager(); 22 | -------------------------------------------------------------------------------- /src/context/auth-context.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, ReactNode } from 'react'; 2 | import useAuth from '../hooks/useAuth'; 3 | 4 | type AuthContextType = ReturnType; 5 | const AuthContext = createContext(undefined); 6 | 7 | export function AuthProvider({ children }: { children: ReactNode }) { 8 | const auth = useAuth(); 9 | return {children}; 10 | } 11 | 12 | export function useAuthContext() { 13 | const context = useContext(AuthContext); 14 | if (context === undefined) throw new Error('useAuthContext must be used within an AuthProvider'); 15 | return context; 16 | } 17 | -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Textarea = React.forwardRef< 6 | HTMLTextAreaElement, 7 | React.ComponentProps<"textarea"> 8 | >(({ className, ...props }, ref) => { 9 | return ( 10 |