Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
6140311
application UI done
AshvikMishra Aug 5, 2025
eb6440e
integrated provider for chats and chat lists
AshvikMishra Aug 5, 2025
68a26dc
integrated provider in more pages + fixed chat replies and expanded m…
AshvikMishra Aug 5, 2025
97fa2f0
removed redundant files
AshvikMishra Aug 5, 2025
e63f961
made the code more modular
AshvikMishra Aug 5, 2025
109d518
[✅] removed everything but text based input
AshvikMishra Aug 9, 2025
243989c
added support for groups and messages from different users
AshvikMishra Aug 9, 2025
8b85d5b
profile gets data from each group
AshvikMishra Aug 9, 2025
7f4a7a3
refactored code to be more modular
AshvikMishra Aug 9, 2025
ec2c28a
filters now work on group page
AshvikMishra Aug 9, 2025
cf691bb
redundant stats page removed
AshvikMishra Aug 9, 2025
b12f7da
theme colors are consistent
AshvikMishra Aug 9, 2025
50325c4
removed redundnt pages
AshvikMishra Aug 9, 2025
aca4f9e
chore: minor fixes
AshvikMishra Sep 2, 2025
31c86ea
feat: sign in and register user works
AshvikMishra Sep 2, 2025
9f822c1
feat: verification page added
AshvikMishra Sep 2, 2025
fee0ae6
feat: leetcode verification works, you can join public groupchats?
AshvikMishra Sep 2, 2025
7b07bce
feat: integrated dashboard partially
AshvikMishra Sep 2, 2025
af37a4c
feat: settings page integration complete
AshvikMishra Sep 28, 2025
795cf2c
feat: cleaned up the dashboard
AshvikMishra Sep 28, 2025
db89db6
feat: refresh on dashboard page
AshvikMishra Sep 28, 2025
6fdce0c
feat: can create update and dleet groups
AshvikMishra Sep 28, 2025
ec09f84
feat: verification skip works + tweaks to groupinfo pages
AshvikMishra Sep 28, 2025
c7a96f8
feat: enhance XP table sorting by streak, solved, and username
AshvikMishra Sep 28, 2025
b4a0c74
cleanup: UI tweaks
AshvikMishra Sep 28, 2025
dabf17f
feat: chat flow
AshvikMishra Sep 30, 2025
d3fbef0
feat: complete backedn integration with messaging 🥳
AshvikMishra Oct 1, 2025
cd1b382
chore: UI cleanup groups and settings page
AshvikMishra Oct 1, 2025
3f315ae
chore: updated dashboard ui
AshvikMishra Oct 1, 2025
b4acbd2
chore: small tweaks to groupinfo page
AshvikMishra Oct 1, 2025
63fc91d
chore: dashboard ui cleanup
AshvikMishra Oct 1, 2025
d595c56
feat: added page when device is offline
AshvikMishra Oct 1, 2025
ff47b6c
chore: UI tweaks dashboard
AshvikMishra Oct 1, 2025
ca7cc5f
chore: fixed options in group info
AshvikMishra Oct 1, 2025
badf7da
feat: added filter to group chat lists page
AshvikMishra Oct 1, 2025
815e1db
chore: UI tweak group page + remove reply feature
AshvikMishra Oct 1, 2025
ef17d03
chore: fixed time issue with messages
AshvikMishra Oct 1, 2025
fb4d74d
chroe: UI tweaks edit groups
AshvikMishra Oct 1, 2025
b773cd8
chore: UI tweaks groupinfo
AshvikMishra Oct 2, 2025
bca4eb7
chore: UI cleanup settings page
AshvikMishra Oct 2, 2025
24e52b7
feat: UI overhaul chat page
AshvikMishra Oct 2, 2025
7f75569
feat: logo done 🥳
AshvikMishra Oct 2, 2025
2806ff5
feat: updated logos -> app icon, splash screen, pages in the app
AshvikMishra Oct 2, 2025
729d563
chore: onboarding color changes
AshvikMishra Oct 2, 2025
c31625b
chore: ui cleanup
AshvikMishra Oct 2, 2025
d57467f
chore: changed android application name
AshvikMishra Oct 2, 2025
cdc88f1
fix: replace fixed width with Spacer for better layout in message dis…
AshvikMishra Oct 2, 2025
64d8037
chore: semi-fix chat re-entering
AshvikMishra Oct 2, 2025
873f2c8
fix: LOGOUT NOT WORKING PATCHED
AshvikMishra Oct 2, 2025
a35fe0c
fix: update button colors for consistency across pages
AshvikMishra Oct 2, 2025
44e3ce4
chore: changed app name
AshvikMishra Oct 21, 2025
b929b6b
fix: auth settings
AshvikMishra Oct 21, 2025
09e89ab
feat: auth refresh + group flow fix
AshvikMishra Oct 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions leaderboard_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
45 changes: 45 additions & 0 deletions leaderboard_app/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "02da4cc00db9eb97fc48e89d319ef48518c2440a"
channel: "master"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: android
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: ios
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: linux
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: macos
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: web
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
- platform: windows
create_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a
base_revision: 02da4cc00db9eb97fc48e89d319ef48518c2440a

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
170 changes: 170 additions & 0 deletions leaderboard_app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# leaderboard_app

Flutter application with backend integration using `dio` + `retrofit` for typed HTTP APIs.

## Backend Integration

We use:

* `dio` for HTTP transport, interceptors, timeouts.
* `retrofit` for declarative REST interface generation (`lib/services/core/rest_client.dart`).
* `build_runner` + `retrofit_generator` (and `json_serializable` if/when model code generation is added).

### Generating code

Run code generation after updating API interface annotations:

```bash
dart run build_runner build --delete-conflicting-outputs
```

### Using the REST client

```dart
import 'package:leaderboard_app/services/core/dio_provider.dart';
import 'package:leaderboard_app/services/core/rest_client.dart';

final dio = await DioProvider.getInstance();
final api = RestClient(dio);

final start = await api.startVerification({'leetcodeUsername': 'someUser'});
final status = await api.getVerificationStatus('someUser');
```

Auth tokens (JWT) are automatically attached from `SharedPreferences` via an interceptor in `DioProvider`.

### Environment / Base URL

Centralized in `lib/config/api_config.dart`.

Default baked-in base URL (when no override is supplied):

```
http://140.238.213.170:3002/api
```

Override at build/run time:

```bash
flutter run --dart-define=API_BASE_URL=https://your.api.host/api
```

Release / CI example:

```bash
flutter build apk --dart-define=API_BASE_URL=https://prod.api.host/api
```

Trailing slashes are trimmed automatically. Keep `/api` if your backend routes are under that prefix.

### Adding new endpoints

1. Edit `lib/services/core/rest_client.dart` – add a method with appropriate HTTP verb annotation.
2. Run the build command above to regenerate `rest_client.g.dart`.
3. Consume the new method from services or providers.

### Logging & Retry

`DioProvider` adds a lightweight log interceptor and simple retry (only once) for idempotent GET requests on connection errors.

---

Generated code (`rest_client.g.dart`) should not be manually edited.


## Building a Release APK / Sharing the App

1. (Optional) Override the API base URL at build time (recommended for different envs):

```bash
flutter build apk --release --dart-define=API_BASE_URL=https://prod.api.host/api
```

If you omit `--dart-define` the baked-in default from `ApiConfig` is used.

2. The unsigned release APK will be at:

```
build\app\outputs\flutter-apk\app-release.apk
```

3. (Recommended) Create a keystore and configure signing in `android/key.properties` + `build.gradle` to avoid Play Store rejection and to allow in-place upgrades.

### Example keystore creation (run once)

```bash
keytool -genkey -v -keystore my-release-key.keystore -alias upload -keyalg RSA -keysize 2048 -validity 10000
```

Place the keystore under `android/` (never commit to VCS) and add a `key.properties`:

```
storePassword=YOUR_STORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=upload
storeFile=../my-release-key.keystore
```

Then update `android/app/build.gradle` signingConfigs + buildTypes (if not already present).

### Distributing for quick tests

You can directly share `app-release.apk` with testers (they must enable install from unknown sources). For Play Store publishing prefer an AAB:

```bash
flutter build appbundle --dart-define=API_BASE_URL=https://prod.api.host/api
```

## Troubleshooting: "Cannot reach server. Check BASE_URL..."

This message originates from `ErrorUtils.fromDio` when the `DioExceptionType.connectionError` occurs. Common causes:

| Cause | Fix |
|-------|-----|
| Device has no internet | Ensure Wi‑Fi/data works (open a website) |
| Backend URL wrong or down | Open the URL in mobile Chrome to verify response |
| Using `localhost` / private IP not reachable externally | Use a public/stable host or expose via tunneling (ngrok, Cloudflare) |
| HTTP blocked (if you switch to HTTPS only) | Ensure correct scheme in `API_BASE_URL` |
| Missing INTERNET permission | Manifest now includes `<uses-permission android:name="android.permission.INTERNET" />` |

To quickly verify the URL the app is using, add a temporary log:

```dart
print('API base URL: ' + ApiConfig.baseUrl);
```

Or run with an override:

```bash
flutter run --release --dart-define=API_BASE_URL=https://your-temp-api/api
```

If the backend uses a self-signed certificate, Android may reject it—use a valid cert (Let's Encrypt) for production.

## Future Enhancements (Optional)

* Add build flavors: dev / staging / prod with per-flavor `--dart-define` presets.
* Add environment banner in-app for non-prod.
* Implement exponential backoff retries for transient network errors.
* Add Sentry or similar for error monitoring.

## Splash Screen & Offline Handling

The app shows a native splash (configured via `flutter_native_splash`) while core services initialize. For returning users (flag stored in `SharedPreferences` as `returningUser`), dashboard data is preloaded (daily question, submissions if verified, leaderboard) before removing the splash to deliver a populated home view quickly.

If there's no network connectivity at launch, a dedicated offline screen (`NoInternetPage`) is displayed. Connectivity is monitored with `connectivity_plus` through `ConnectivityProvider`; once a connection becomes available the app automatically proceeds with initialization and dismisses the splash.

Update splash assets/colors in `pubspec.yaml` under `flutter_native_splash:` then regenerate:

```bash
flutter pub run flutter_native_splash:create
```

Key files:

* `lib/main.dart` – splash preservation & initialization logic (`_AppInitializer`).
* `lib/provider/connectivity_provider.dart` – connectivity listener.
* `lib/pages/no_internet_page.dart` – offline UI.

To disable preloading behavior simply remove the `dashboardProvider.loadAll()` call in `_preload()`.

1 change: 1 addition & 0 deletions leaderboard_app/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: package:flutter_lints/flutter.yaml
14 changes: 14 additions & 0 deletions leaderboard_app/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/

# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
44 changes: 44 additions & 0 deletions leaderboard_app/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}

android {
namespace = "com.dscvit.leeterboard"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.dscvit.leeterboard"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}

flutter {
source = "../.."
}
7 changes: 7 additions & 0 deletions leaderboard_app/android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
50 changes: 50 additions & 0 deletions leaderboard_app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Network permissions required for API calls in release builds -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:label="LeeterBoard"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.dscvit.leeterboard

import io.flutter.embedding.android.FlutterActivity

class MainActivity : FlutterActivity()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading