A Nonton Bareng project.
The Nobar (Nonton Bareng) project is a Flutter-based mobile application designed to facilitate a seamless "watch together" experience. It integrates with backend APIs for features like login, movie listings, and logging. The app employs modern Flutter practices and tools for state management and UI customization.
This project is a full-stack application that includes:
- Backend : A Node.js server with Express, SQLite database, and APIs for user authentication (login & register), chat, video list & detail, logs, and email.
- Frontend : A react-based web app for displaying logs and interaction with backend.
- Mobile : A flutter based app for displaying video list, play video & chat & interaction with backend.
Features :
- User authentication with hashed passwords.
- Real-time chat using Socket.IO.
- Logging of all API interaction and chat messages.
- Sending emails using Nodemailer.
- Displaying logs in a web dashboard.
- Video streaming.
Prerequisites : Before setting up the project, ensure the following tools are installed:
- Flutter SDK: Version 3.0 or higher
- Dart SDK: Included with Flutter
- Android Studio or VS Code: For development and testing
- Node.js: To run the backend API (if integrating with it)
- Git: For version control
- Reactjs: Version 18.3.1 for Dashboard web app
server ├── app.js # Main server setup ├── config/ │ └── database.js # SQLite database configuration | ├── emailConfig.js # Nodemailer transporter setup ├── constants/ │ └── index.js ├── controllers/ │ ├── authController.js # User login and registration │ ├── chatController.js # Real-time chat logic │ ├── logController.js # Logging API logic │ ├── emailController.js # Email sending logic │ └── videoController.js # Video list & detail logic ├── middleware/ │ └── authMiddleware.js ├── models/ │ ├── log.js │ ├── user.js │ └── video.js ├── package-lock.json ├── package.json # Node.js dependencies and scripts ├── routes/ │ ├── authRoutes.js # Auth endpoints │ ├── chatRoutes.js # Chat endpoints │ ├── logRoutes.js # Log endpoints │ ├── emmailRoutes.js # Email endpoints │ └── videoRoutes.js # Video endpoints ├── server.js ├── services/ │ ├── responseService.js │ └── videoService.js └── videos.db # SQLite database file Postman collection can be downloaded here
Authentication
-
POST
/api/auth/register- Register a new user.
- Request body:
{ "username": "user@example.com", "password": "securepassword" } - Response:
{ "message": "User registered successfully" }
-
POST
/api/auth/login- Authenticates a user and returns a token.
- Request body:
{ "username": "user@example.com", "password": "securepassword" } - Response:
{ "token": "JWT_TOKEN" }
Logs
-
GET
/api/logs- Retrieves all logs in reverse chronological order.
- Response:
[{ "id": 1, "message": "User logged in", "time": "2024-11-13T12:00:00Z" }, { "id": 2, "message": "Chat: Hello, world!", "time": "2024-11-13T12:01:00Z" }]
-
POST
/api/logs- Creates a new log entry.
- Request body:
{"message": "Log message"} - Response:
{"message": "Log created"}
Chats
- WebSocket Endpoint :
/chat- Connects authenticated users for real-time chat.
- POST
/api/email/send- Sends an email..
- Request body:
{ "to": "recipient@example.com", "subject": "Subject text", "text": "Body text" } - Response:
{"message": "Email sent successfully"}
Users Table
| Field | Type | Description |
|---|---|---|
| id | INTEGER | Primary Key |
| username | TEXT | Email of the user (unique) |
| password | TEXT | Hashed password |
Logs Table
| Field | Type | Description |
|---|---|---|
| id | INTEGER | Primary Key |
| message | TEXT | Log message |
| time | TIMESTAMP | Time of log creation |
Videos Table
| Field | Type | Description |
|---|---|---|
| id | INTEGER | Primary Key |
| title | TEXT | Video title |
| description | TEXT | Video description |
| url | TEXT | Video URL |
| createdAt | TIMESTAMP | Time of video creation |
Chats Table
| Field | Type | Description |
|---|---|---|
| id | INTEGER | Primary Key |
| username | TEXT | User's email |
| text | TEXT | Chat description |
| time | TIMESTAMP | Time of chat creation |
logs-dashboard ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src ├── App.css ├── App.js ├── App.test.js ├── components │ ├── Login.js │ └── LogsDashboard.js ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js └── setupTests.js Login.js
- Display login page & redirect to dashboard when success.
- browse to
{yourLocalWebApp}/loginto access the Login page.
LogsDashboard.js
- Fetches logs from the
/api/logsendpoint and displays them in a table. - Browse to
{yourLocalWebApp}/dashboardto access the Dashboard page, token is required so do login first to open it, if not you'll be kicked to Login page.
. ├── analysis_options.yaml ├── assets/ │ ├── fonts/ │ │ ├── Poppins-Light.ttf │ │ ├── Poppins-Regular.ttf │ │ └── Poppins-SemiBold.ttf │ └── images/ │ └── img_splash.png ├── flutter_native_splash.yaml ├── lib/ │ ├── app/ │ │ └── app.dart │ ├── config/ │ │ ├── app_colors.dart │ │ ├── app_constants.dart │ │ ├── app_strings.dart │ │ ├── app_text_theme.dart │ │ ├── app_theme.dart │ │ └── image_constants.dart │ ├── core/ │ │ ├── data_source/ │ │ │ ├── log_endpoint.dart │ │ │ ├── login_endpoint.dart │ │ │ ├── movie_list_endpoint.dart │ │ │ └── register_endpoint.dart │ │ ├── domain/ │ │ │ ├── message.dart │ │ │ ├── message.freezed.dart │ │ │ ├── message.g.dart │ │ │ ├── movie.dart │ │ │ ├── movie.freezed.dart │ │ │ ├── movie.g.dart │ │ │ ├── register.dart │ │ │ ├── register.freezed.dart │ │ │ └── register.g.dart │ │ ├── extension/ │ │ │ └── datetime_extension.dart │ │ ├── navigation/ │ │ │ ├── page_list.dart │ │ │ └── pages.dart │ │ ├── network/ │ │ │ ├── api_constants.dart │ │ │ ├── api_exception.dart │ │ │ ├── api_response.dart │ │ │ ├── api_response.g.dart │ │ │ └── auth_interceptor.dart │ │ ├── repository/ │ │ │ ├── auth_repository.dart │ │ │ └── movie_repository.dart │ │ ├── service/ │ │ │ ├── api_service.dart │ │ │ ├── log_service.dart │ │ │ └── storage_service.dart │ │ └── view/ │ │ ├── credential_form.dart │ │ ├── empty_view.dart │ │ ├── error_view.dart │ │ ├── in_app_message.dart │ │ ├── loading_view.dart │ │ └── nobar_loading.dart │ ├── main.dart │ └── screen/ │ ├── detail/ │ │ ├── controller/ │ │ │ └── detail_controller.dart │ │ └── view/ │ │ └── detail_screen.dart │ ├── list/ │ │ ├── controller/ │ │ │ ├── list_controller.dart │ │ │ └── movie_card_controller.dart │ │ └── view/ │ │ ├── empty_chat.dart │ │ ├── list_screen.dart │ │ ├── message_card.dart │ │ └── movie_card.dart │ ├── login/ │ │ ├── controller/ │ │ │ └── login_controller.dart │ │ └── view/ │ │ └── login_screen.dart │ └── register/ │ ├── controller/ │ │ └── register_controller.dart │ └── view/ │ └── register_screen.dart ├── nobar.iml ├── pubspec.lock ├── pubspec.yaml └── test └── widget_test.dart - Clone the repository:
git clone <repository-url> cd project-root/server
- Install dependencies:
npm install
- Start the server:
npm start
- Navigate to the React project directory:
cd project-root/logs-dashboard - Install dependencies:
npm install
- Start the server:
npm start
- Navigate to the Flutter project directory:
cd project-root/mobile - Run the following command to fetch the required Flutter packages:
flutter pub get
- Set your API base url in baseUrl in lib/config/app_constants.dart file :
baseUrl = 'host:port' - Connect an emulator or physical device and run :
flutter run
| Page | Screenshot |
|---|---|
| Login | ![]() |
| Dashboard | ![]() |
| Screen | Screenshot |
|---|---|
| Splash | ![]() |
| Login | ![]() |
| Register | ![]() |
| Video List | ![]() |
| Video Detail | ![]() |
| Chat | ![]() |
| Nobar Invitation | ![]() |
| Video Fullscreen | ![]() |









