Inspiration

Winnipeg has extreme seasons, and the weather changes how we feel. We wanted a fun way to turn that shared feeling into something social—so instead of everyone streaming alone, people can instantly join a room and listen together. We also wanted the project to feel Winnipeg-first by adding an “Explore Winnipeg” section to highlight local places, culture, and traditions.

What it does

Nexus turns the current weather in Winnipeg into a mood, then starts a synced listening room where everyone hears the same track at the same moment (phone + web).

Core features:

  • Weather → Mood: Pulls live Winnipeg weather (OpenWeather) and maps it into a mood (Cozy/Chill/Focus/Hype, etc.).
  • Create/Join Room: Users enter their name, create a room (auto-generates a 6-digit code), or join with a code.
  • Synced Playback: When a room starts, the song start time is scheduled using server time so new joiners play at the same timestamp.
  • Live Chat: Room chat so people can talk while listening.
  • Listener Count: Shows how many people are currently in the room.
  • Voting: While the current track plays, users vote the next track and the highest-voted option becomes next in the queue.
  • Explore Winnipeg (Impact Feature): A curated gallery of local places/culture with images + descriptions to help people learn and connect with Winnipeg.

How we built it

  • Frontend: React Native (Expo) + TypeScript with Expo Router
  • Weather API: OpenWeather (q=Winnipeg,CA&units=metric)
  • Realtime sync + chat + votes: Firebase Realtime Database (RTDB)
  • Audio: Expo AV
  • Sync approach:
    • Store a shared startedAt timestamp (server-aligned) in RTDB
    • Clients compute serverNow() using a live server offset
    • On join, clients seek to serverNow() - startedAt so playback matches the host
  • Explore Winnipeg content: Simple dataset (title, description, image URL) displayed as cards/gallery.

Challenges we ran into

  • Audio sync drift: Different devices load and buffer audio at different speeds, especially web vs phone. We solved this by using a server-time offset and doing a “resync” correction after the track loads.
  • Cross-platform audio quirks: Some audio formats behaved differently on web vs mobile. We adjusted by using a consistent loading/play pipeline and better error handling.
  • Realtime data structure: Designing RTDB paths for rooms, playback sessions, votes, chat, and presence took iteration to avoid conflicts and keep it simple.

Accomplishments that we're proud of

  • A working MVP that syncs the same music moment across multiple clients.
  • Real-time features working together: presence count, chat, votes, and playback state.
  • A strong “Winnipeg impact” direction with Explore Winnipeg, turning the app into more than just a music tool.

What we learned

  • Real-time synchronization is more than “play at the same time”—you need server time, buffering strategy, and drift correction.
  • Firebase RTDB is great for fast prototyping of real-time interactions (chat/votes/presence).
  • Building for web + mobile at once reveals edge cases early and makes the product stronger.

What's next for Nexus

  • Better queue system: lock in “current track”, then automatically switch to the winning next track at the end.
  • More moods + playlists: 3+ curated tracks per mood, with local Winnipeg artists featured.
  • Explore Winnipeg expansion: add Indigenous culture spotlights, event highlights, and community submissions.
  • Room moderation + safety: basic filters, report tools, and better room controls.
  • Location support: allow any city (not only Winnipeg) while keeping Winnipeg as the featured default.

Built With

  • chat
  • expo-av
  • expo-router
  • firebase
  • github
  • openweather
  • openweather-api
  • playback-sync
  • presence
  • react-native
  • typescript
  • typescript-?-react-native-(expo)-?-expo-router-?-expo-av-(audio-playback)-?-firebase-realtime-database-(rooms
Share this project:

Updates