Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📍 Yapper — Location-Based Anonymous Chat

Python FastAPI React WebSockets TailwindCSS

💬 No sign-up. No followers. Just people near you, talking right now.

Yapper is a full-stack, real-time chat app where rooms are tied to a physical location instead of a topic or a friend list. You only see rooms created near you, and they disappear on their own after a couple of hours — so it's less "social network" and more "who's around right now."


✨ What it does

  1. 📍 Finds your location — the browser's Geolocation API grabs your coordinates on load (with your permission).
  2. 🗺️ Shows nearby rooms — the backend calculates the distance from you to every active room using the Haversine formula and only returns ones within a 5 km radius.
  3. Create a room — spin up a new room at your current location in a couple of taps; no account needed.
  4. Rooms self-destruct — every room carries a created_at / expires_at pair and auto-expires 2 hours after creation, keeping the map fresh.
  5. Chat in real time — once inside a room, messages flow over a WebSocket connection, broadcast instantly to everyone else in that room.
  6. 👤 Anonymous by design — no login. A random client_id is generated and persisted in localStorage, paired with whatever nickname you type in — that's your identity for the session.
  7. 🚫 One room at a time — the backend's connection manager tracks which client is in which room and rejects a second simultaneous room connection from the same client.
  8. 🕓 Message history — join a room and instantly get replayed the existing conversation, pulled from the database over the same socket.

🗂️ Project structure

yapper/
├── backend/                         # 🐍 FastAPI application
│   ├── requirements.txt
│   └── app/
│       ├── main.py                  # 🚀 app entrypoint — routes + WebSocket wiring
│       ├── config.py                # ⚙️  env-driven settings (DB url, radius, TTL)
│       ├── database.py              # 🗄️  SQLModel engine + session setup
│       │
│       ├── api/v1/
│       │   ├── rooms.py             #     POST /rooms, GET /rooms/nearby
│       │   └── messages.py          #     GET /rooms/{id}/messages (history)
│       │
│       ├── core/
│       │   └── geo.py               # 📐 Haversine distance + radius check
│       │
│       ├── models/                  # 🧱 SQLModel tables
│       │   ├── room.py              #     Room (location, TTL, active flag)
│       │   └── message.py           #     Message (room_id, sender, content)
│       │
│       ├── schemas/                 # 📦 Pydantic request/response shapes
│       │   ├── room.py
│       │   └── message.py
│       │
│       ├── services/                # 🧠 business logic, decoupled from routes
│       │   ├── room_service.py      #     create/find nearby rooms, expire stale ones
│       │   └── message_service.py   #     persist + fetch messages
│       │
│       └── websocket/
│           ├── connection_manager.py #    tracks room ↔ socket ↔ client mappings
│           └── handlers.py           #    join / broadcast / disconnect logic
│
└── frontend/                        # ⚛️ React application
    └── src/
        ├── App.jsx                  # 🧠 top-level state, geolocation, WebSocket client
        ├── index.css                # 🎨 Tailwind entrypoint
        └── components/
            ├── LandingPage.jsx      #     nickname entry screen
            ├── Sidebar.jsx          #     app shell / navigation
            ├── RoomList.jsx         #     nearby rooms list
            ├── CreateRoomModal.jsx  #     "create a room here" form
            └── ChatArea.jsx         #     message list + composer

🛠️ Tech stack

Layer Tech
Backend framework FastAPI (async Python)
Real-time layer native WebSockets (FastAPI/Starlette)
ORM / models SQLModel (SQLAlchemy + Pydantic) over SQLite
Config pydantic-settings + .env
Frontend React 19, Tailwind CSS, lucide-react icons
Location logic Browser Geolocation API + server-side Haversine formula
Server Uvicorn

✅ Prerequisites

  • 🐍 Python 3.11+
  • 🟢 Node.js 18+ and npm
  • A browser that supports the Geolocation API (all modern browsers)

🛠️ Setup

1️⃣ Backend

cd backend
python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate

pip install -r requirements.txt
uvicorn app.main:app --reload  # runs on http://127.0.0.1:8000

2️⃣ Frontend

cd frontend
npm install
npm start                      # runs on http://localhost:3000

Open the app, allow location access, pick a nickname, and either join a room from the list or create a new one at your current location. 📍


🧠 How it's built

  • 📐 Room discovery: GET /api/v1/rooms/nearby?lat=..&lon=.. fetches all active rooms and filters them with the Haversine formula against a configurable MAX_DISTANCE_KM.
  • Expiry: rooms are lazily expired — any room whose expires_at has passed is flipped to inactive the next time the nearby-rooms endpoint runs.
  • Live messaging: the frontend opens ws://.../ws/{room_id}, sends a join event with { nickname, client_id }, receives the existing message history, then sends/receives message events for the rest of the session.
  • 🧵 Connection management: an in-memory ConnectionManager maps room_id → [sockets] and client_id → room_id, broadcasting new messages to every socket in a room and blocking a client from being in two rooms at once.
  • 💾 Persistence: every message is written to SQLite via SQLModel before being broadcast, so history survives reconnects.

⚠️ Notes and limitations

  • 🔓 There's no real authentication yet — identity is just a nickname + a locally-stored client_id. python-jose and passlib are in requirements.txt for future JWT-based auth but aren't wired in yet.
  • 🗄️ Uses SQLite by default — fine for local dev/demo, but swap DATABASE_URL for Postgres before deploying anywhere with concurrent traffic.
  • 🌐 CORS is wide open (allow_origins=["*"]) for local development — lock this down before deploying publicly.
  • 📍 Distance is calculated as-the-crow-flies (straight-line), not walking/driving distance.

Made with ☕ and a bit too much curiosity about who else is nearby.

About

A real-time, location-based anonymous chat app to discover and join chat rooms within 5km of you, message live over WebSockets, and watch rooms auto-expire after 2 hours. Built with FastAPI, SQLModel, React 19, and Tailwind CSS.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages