Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 61 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Release AccessSetu

on:
push:
branches:
- access-setu
tags:
- 'v*'
- 'test*'
workflow_dispatch:

permissions:
contents: write

jobs:
release:
name: Build & Release APK
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true

- name: Build Release APK
run: |
flutter pub get
flutter build apk --release
cp build/app/outputs/flutter-apk/app-release.apk AccessSetu-test.apk
cp build/app/outputs/flutter-apk/app-release.apk AccessSetu-release.apk

- name: Determine Tag Name
id: tag
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
else
echo "name=test" >> $GITHUB_OUTPUT
fi

- name: GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.name }}
name: AccessSetu Test Release (${{ steps.tag.outputs.name }})
files: |
AccessSetu-test.apk
AccessSetu-release.apk
generate_release_notes: true
42 changes: 31 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,61 @@
*.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/
# Visual Studio Code
.vscode/

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

# Symbolication related
# Symbolication & Obfuscation
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
# Android
.gradle/
/android/.gradle/
/android/local.properties
/android/key.properties
*.keystore
*.jks
/android/app/debug
/android/app/profile
/android/app/release
/android/build/
*.apk
*.aab

# Ensure Gradle wrapper is tracked for CI/CD builds
!**/android/**/gradle/wrapper/gradle-wrapper.jar
!**/gradle/wrapper/gradle-wrapper.jar

# iOS
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/xcuserdata
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/flutter_export_environment.sh
**/ios/Runner/GeneratedPluginRegistrant.*

# Workspace / Agent scratch files
.agents/
PROJECT_AUDIT.md
182 changes: 105 additions & 77 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,97 +1,125 @@
# AccessMap

AccessMap is an accessibility-first community map for discovering places that are welcoming and usable for people with different accessibility needs.

The MVP starts directly with onboarding, stores a mock user profile, and runs on demo data so it can be shown reliably without authentication, backend setup, or API keys.

## Features

- PA Assisted and Solo onboarding modes
- Accessibility need selection for Can't Talk, Can't Speak, and Can't See
- Extensible accessibility profile model, including wheelchair and physical accessibility needs
- Interactive OpenStreetMap map using `flutter_map`
- Accessibility-focused search, category filters, and high-friendly filtering
- Tappable place markers with preview cards (score, distance, confirmations)
- "Get Directions" opens the venue's real Google Maps entry (each demo place carries an actual Google Maps link; falls back to coordinate-based routing)
- Full place detail pages with Friendly Score, profile-aware Wheelchair-Friendly score, category scores with progress bars, score explanation sheets, tags, confirmations, and reviews
- Tap-any-score explanation ("Based on: 43 community reviews ...")
- Feature-level community confirmation (+3 points) with last-confirmed dates
- Structured 1-10 review submission across staff, communication, assistance, physical access, facilities, and overall experience
- Helpful votes, report review, community points, and contribution history
- Community location submission: 5-step Add Location flow (pick on map or search, basic info, tri-state accessibility survey, photos, review) with duplicate detection, +10 points, provisional "New" scores until the community rates the place, and offline persistence via SharedPreferences
- Report incorrect place information
- Discover screen with category chips, Popular Near You, Highly Rated by Community, and Recently Added
- Profile editor with a demo wheelchair profile toggle for showing personalization behavior
# AccessSetu (एक्सेस सेतु)

> **Bridging Accessible Mobility, Spoken Guidance, and Community Confidence**

AccessSetu is an accessibility-first Flutter application designed to empower individuals with physical, sensory, and communication needs. Engineered around real-world accessibility infrastructure in Goa, India, AccessSetu combines spatial mapping, spoken landmark navigation, offline resilience, digital disability credentials, and emergency tools into a unified, privacy-focused mobile experience.

---

## Core Features

### 1. Accessible Map & Spatial Discovery
- **Interactive Geospatial Map**: OpenStreetMap rendering powered by `flutter_map` and `latlong2`.
- **Multi-Style Map Layers**: Toggle between Standard OSM, Satellite View, and Public Transport layers.
- **3D Perspective Tilt Mode**: Perspective tilt and rotation for depth perception and street orientation.
- **Live GPS Tracking**: One-tap center-and-follow positioning with real-time accuracy and weak-signal fallbacks.
- **Accessibility Filtering**: Filter places by category (Hospitals, Restaurants, Transit, Pharmacies), high friendliness threshold (8.5+), and travel mode suitability.

### 2. Multi-Modal Navigation & Spoken Turn Guidance (OSRM)
- **Open-Source Pedestrian & Vehicle Routing**: Direct integration with OSRM (Open Source Routing Machine) for real street navigation:
- 🚶 **Walk**: Sidewalks, pedestrian crossings, footpaths, and step-free routes.
- 🚴 **Bike**: Cycling corridors and bike-friendly roads.
- 🚗 **Car**: Vehicular driving routes.
- **15-Second Periodic Voice Guidance**: When navigating, if stationary or paused, spoken prompts announce exact turn degrees and remaining distance (e.g., *"Turn 19 degrees right, then walk 45 meters"*).
- **Gyroscope & Compass Dial**: Real-time compass heading with live relative angle badge (`R19°`, `L25°`, `0°`) pointing directly toward the next maneuver.
- **Dynamic Travel Time & Speed**: ETA adjusts in real-time based on live GPS walking/driving speed.
- **"Where Am I?" Spatial Orientation**: Spoken announcement providing heading, street location, and nearest verified landmark.
- **Proximity Hazard Alerts**: Audio warnings when approaching reported obstacles (broken ramps, construction, missing tactile paving).

### 3. Digital Disability Pass & UDID Medical ID
- **Offline Assistance ID Card**: High-contrast digital ID modeled after official credentials for transit conductors and staff.
- **UDID Verification & Details**: Displays UDID number, disability category, percentage, issuing authority, and dates.
- **Smart Document Scanner (OCR)**: On-device optical character recognition via Google ML Kit to extract UDID certificate numbers from physical documents.
- **ICE Medical Card & Emergency QR**: Instant access to blood group, conditions, allergy notes, and emergency medical QR code.

### 4. Smart SOS Safety Beacon
- **Accidental-Tap Protection**: 3-second interactive countdown with cancel button and vibration feedback.
- **Audible Siren Beacon**: High-volume repeating siren loop for immediate personal safety and bystander alerting.
- **Voice Help Broadcast**: Synthesized emergency speech loop announcing identity and distress message.
- **1-Tap ICE Dialer**: Pre-configured emergency contacts (family, doctor, helpline) with direct phone and SMS dispatch.

### 5. Offline Map Package Management
- **Regional Offline Packs**: Download focused offline tile packages:
- **Panaji City Center & Mandovi** (~45 MB)
- **North Goa Coastal Belt** (~85 MB)
- **South Goa Heritage & Margao** (~65 MB)
- **Storage Management**: Progress-tracked downloads, local storage accounting, and one-tap deletion.

### 6. Community Place Submission & Reviews
- **5-Step Location Submission Wizard**: Add missing places with interactive map pin picker, reverse geocoding, duplicate detection, tri-state accessibility survey, photo placeholders, and +10 Community Points.
- **Local Persistence**: Community submissions persist offline via SharedPreferences alongside seed demo places.
- **Feature Confirmation (+3 Points)**: Verify individual accessibility features (step-free ramps, wide doors, braille, elevators).
- **Structured 1-10 Reviews (+5 Points)**: Multi-dimensional ratings across staff, communication, assistance, physical access, and restrooms.
- **Community Points & History**: Earn points toward local access advocate badges with activity tracking.

---

## Tech Stack

- Flutter and Dart
- Provider for state management
- `flutter_map` with OpenStreetMap demo tiles
- `speech_to_text` behind a `VoiceSearchService` abstraction
- `url_launcher` behind a `NavigationService`
- Mock repositories for places and reviews, with a SharedPreferences-backed store for community-contributed places
- `geolocator` + local fallback geocoding behind a `GeocodingService` for location search and reverse geocoding
- **Framework**: Flutter 3.x / Dart 3.x
- **State Management**: `provider` (`AppState`)
- **Map & Geolocation**: `flutter_map`, `latlong2`, `geolocator`, `geocoding` (`GeocodingService`)
- **Routing Engine**: OSRM API (Walk `/foot`, Bike `/bike`, Car `/driving`)
- **Speech & Audio**: `flutter_tts`, `speech_to_text`, `audioplayers`
- **Machine Learning**: `google_mlkit_text_recognition`
- **Hardware & Sensors**: `flutter_compass`, `vibration`, `image_picker`, `qr_flutter`
- **CI/CD**: GitHub Actions automated release pipeline

## Running the Project
---

```bash
flutter pub get
flutter run
## Project Structure

```text
.github/
└── workflows/
└── release.yml # Automated APK release pipeline
lib/
├── app/
│ ├── access_map_app.dart # Root MaterialApp
│ └── app_state.dart # Main state coordinator
├── core/
│ ├── services/ # OSRM routing, TTS, exploration, offline maps, OCR
│ ├── theme/ # App theme, typography, colors
│ └── utils/ # Visibility policies and math helpers
├── features/
│ ├── contributions/ # Points, activity history, and review summaries
│ ├── emergency/ # SOS beacon, siren, and ICE contacts
│ ├── map/ # MapScreen, 3D tilt, Discover tab, navigation HUD
│ ├── onboarding/ # Welcome onboarding & persona selection
│ ├── places/ # Place details, friendly score sheets, directions
│ ├── profile/ # Profile settings, Disability Pass, Offline Maps
│ └── reviews/ # Structured 1-10 review submission
└── shared/
├── models/ # Place, UserProfile, Hazard, MapStyle models
└── widgets/ # Buttons, search bar, cards, bottom sheets
```

Run tests with:
---

```bash
flutter test # 40 tests: unit + acceptance + add-location flow
flutter analyze # static analysis
```
## Quickstart

Build and install the Android APK:
### Run Locally

```bash
flutter build apk --debug # or: cd android && ./gradlew assembleDebug
adb install -r build/app/outputs/flutter-apk/app-debug.apk
flutter pub get
flutter run
```

If `flutter build apk` fails with an NDK version error on your machine, use the Gradle wrapper directly (`cd android && ./gradlew assembleDebug`) — both produce the same APK.
### Build Release APK

## Environment Variables and API Keys

No API key is required for the MVP demo mode.

The current map uses OpenStreetMap tiles through `flutter_map`. If the app later moves to Google Maps, Mapbox, or another provider, add the provider key through platform configuration or environment-specific files. Do not hard-code keys in source.

## Architecture

```text
lib/
app/ App root and Provider state controller
core/ Theme, services, visibility policy
features/ Onboarding, map, places, reviews, profile, contributions
shared/models/ User, place, review, feature, category models
shared/widgets/ Reusable UI components
```bash
flutter build apk --release
```

The UI talks to `AppState`, which calls repository/service abstractions. `MockPlaceRepository` is the current backend substitute and can be replaced by API-backed repositories later.
Output APK will be at `build/app/outputs/flutter-apk/app-release.apk`.

## Known Limitations
### Automated GitHub Release (CI/CD)

- Place data and reviews are mock demo data.
- Location permission is represented as a demo action; manual search remains usable.
- Voice search depends on platform speech availability and falls back to a clear message when unavailable.
- Photo upload is modeled as a future backend-backed action.
- Accessibility-aware routing is intentionally not implemented in this MVP.
Tag any commit with `v*` to automatically trigger the GitHub Actions release workflow:

## Acceptance Checklist
```bash
git tag v1.0.0
git push origin access-setu --tags
```

- Launches into onboarding without sign-up
- Select PA Assisted or Solo
- Select an accessibility need
- Opens a map with multiple accessibility-focused places
- Search and select places
- View Friendly Score and relevant accessibility information
- Read contextual community reviews
- Submit a structured review and earn points
- Open profile and contributions
- Add wheelchair need in profile and see Wheelchair-Friendly scores appear
The workflow will compile a production release APK and publish it directly to your repository's **Releases** page as `AccessSetu-release.apk`.
5 changes: 5 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
analyzer:
exclude:
- build/**
- android/**
- ios/**
include: package:flutter_lints/flutter.yaml

linter:
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import java.io.FileInputStream

plugins {
id("com.android.application")
id("kotlin-android")
id("org.jetbrains.kotlin.android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
Expand All @@ -30,7 +30,7 @@ android {

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.accessmap.access_map"
applicationId = "com.accessmap.combined"
// 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
Expand Down
5 changes: 3 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Map tiles + directions links -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Requested at runtime only when the user taps "Use My Current Location" -->
<!-- Location permissions for GPS centering and map picker -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
android:label="access_map"
android:label="AccessSetu (Combined)"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
Expand Down
4 changes: 4 additions & 0 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
buildscript {
extra["kotlin_version"] = "2.2.20"
}

allprojects {
repositories {
google()
Expand Down
4 changes: 4 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
Binary file added android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
Loading
Loading