{"id":35828026,"url":"https://github.com/teamclassify/hublink-app","last_synced_at":"2026-01-07T21:03:00.694Z","repository":{"id":324119569,"uuid":"1077234423","full_name":"teamclassify/hublink-app","owner":"teamclassify","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-12T12:14:17.000Z","size":299,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-12T23:45:52.395Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/teamclassify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-16T01:16:30.000Z","updated_at":"2025-12-12T12:14:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/teamclassify/hublink-app","commit_stats":null,"previous_names":["teamclassify/hublink-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/teamclassify/hublink-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teamclassify%2Fhublink-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teamclassify%2Fhublink-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teamclassify%2Fhublink-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teamclassify%2Fhublink-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/teamclassify","download_url":"https://codeload.github.com/teamclassify/hublink-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teamclassify%2Fhublink-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28237771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-07T02:00:05.975Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-07T21:01:41.720Z","updated_at":"2026-01-07T21:03:00.687Z","avatar_url":"https://github.com/teamclassify.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hublink\n\nHublink is an Android app built with Kotlin and Jetpack Compose that provides user authentication, event creation, image upload, and real-time event listing. It integrates Firebase for authentication and realtime data, and Supabase Storage for hosting uploaded images.\n\n## Tech Stack\n- Kotlin, Coroutines, StateFlow\n- Jetpack Compose, Material 3, Navigation\n- Firebase Authentication, Firebase Realtime Database\n- Supabase Storage (via `io.github.jan.supabase` client)\n\n\u003cimg width=\"1233\" height=\"672\" alt=\"hublink\" src=\"https://github.com/user-attachments/assets/ef40dc8b-4a80-4fba-926b-f927758285d4\" /\u003e\n\n\n## Project Structure\n```\napp/src/main/java/com/classify/hublink/\n├─ HublinkApplication.kt            # Application class \u0026 DI container bootstrap\n├─ MainActivity.kt                  # Compose host, auth-driven navigation\n├─ config/\n│  └─ SupabaseClient.kt            # Supabase client initialization (Storage)\n├─ data/\n│  ├─ AppContainer.kt              # Simple DI container and interfaces\n│  ├─ entities/\n│  │  └─ Event.kt                  # Event data model\n│  └─ repositories/\n│     └─ EventsRepository.kt       # Realtime DB event stream \u0026 create\n├─ ui/\n│  ├─ AppViewModelProvider.kt      # ViewModel factory helpers (if used)\n│  ├─ components/                  # Reusable Compose UI components\n│  │  ├─ CustomButton.kt\n│  │  ├─ ImageUploader.kt\n│  │  ├─ Logo.kt\n│  │  └─ NavigationBar.kt\n│  ├─ screens/                     # Top-level screens\n│  │  ├─ Home.kt\n│  │  ├─ Loading.kt\n│  │  ├─ Login.kt\n│  └─ theme/                       # Material theme setup\n│     ├─ Color.kt\n│     ├─ Dimens.kt\n│     ├─ Theme.kt\n│     └─ Type.kt\n├─ utils/\n│  └─ Password.kt                  # Password helpers\n└─ viewmodel/\n   ├─ AuthViewModel.kt             # Auth state management\n   └─ EventViewModel.kt            # Events stream \u0026 image upload\n```\n\n## Architecture Overview\n- UI is built with Jetpack Compose. `MainActivity` hosts the Compose content and applies the `HublinkTheme`.\n- Navigation is conditionally driven by authentication state exposed by `AuthViewModel`:\n  - Loading → `LoadingScreen`\n  - Authenticated → `NavigationBar` (bottom navigation / main app)\n  - Idle/Error → NavHost with `LoginScreen` and `RegisterScreen`\n- Dependency injection is handled via a lightweight container (`AppContainer` / `AppDataContainer`) initialized in `HublinkApplication`.\n- Data flow for events:\n  - `EventsRepository` listens to Firebase Realtime Database (`/events`) and exposes a `StateFlow\u003cList\u003cEvent\u003e\u003e`.\n  - `EventViewModel` collects the flow as a lifecycle-aware `StateFlow` and offers methods to add events.\n  - Images are uploaded to Supabase Storage bucket `events`; the resulting public URL can be stored alongside event data.\n\n## Key Components\n- Authentication: `AuthViewModel` uses Firebase Auth and exposes `AuthState` sealed class with `Idle`, `Loading`, `Success`, and `Error`.\n- Events: `EventsRepository` streams live updates via a `ValueEventListener` and supports `addNewEvent` for authenticated users.\n- Image Upload: `EventViewModel.uploadImageToSupabase` reads bytes from a `Uri`, uploads to Supabase Storage, and returns a public URL.\n\n## Configuration\nYou must set credentials for Firebase and Supabase.\n\n### Firebase\n- Add Firebase to the Android project (via Firebase Console), enable Email/Password authentication.\n- Add `google-services.json` in `app/` and ensure the Gradle plugin is applied.\n- Realtime Database security rules should allow authenticated users to read/write as appropriate for your app.\n\n### Supabase\nThe Supabase client reads from `BuildConfig` fields in `config/SupabaseClient.kt`:\n- `BuildConfig.SUPABASE_URL`\n- `BuildConfig.SUPABASE_KEY`\n\nIn `local.properties`, add the following:\n\n```kotlin\n// local.properties\nSUPABASE_URL=xxx\nSUPABASE_KEY=xxx\n```\n\nIn Supabase, create a Storage bucket named `events` and enable public access (or implement signed URLs if required).\n\n## Getting Started\n1. Prerequisites\n   - Android Studio Ladybug+ (or newer)\n   - JDK 17 (matching your Android Gradle Plugin requirements)\n   - A configured Firebase project (Auth + Realtime Database)\n   - A Supabase project with a public Storage bucket `events`\n\n2. Clone and open in Android Studio\n   - Sync Gradle\n   - Set up `google-services.json`\n   - Configure `BuildConfig` fields for Supabase\n\n3. Run\n   - Select a device/emulator and Run the app\n\n## How It Works (Flow)\n- App launch initializes `HublinkApplication`, wiring the `AppDataContainer`.\n- `MainActivity` sets Compose content and observes `AuthState` from `AuthViewModel`:\n  - On `Success` → main navigation UI (`NavigationBar`) is shown.\n  - On `Idle`/`Error` → user can login or register.\n- `EventsRepository` listens for realtime updates and updates its `StateFlow`.\n- `EventViewModel` exposes the events to UI screens and allows adding new events.\n- Image upload uses Supabase Storage; the returned URL can be associated with the event.\n\n## Notable Files\n- `HublinkApplication.kt`: Initializes the DI container (`AppDataContainer`).\n- `MainActivity.kt`: Edge-to-edge setup, Compose root, auth-driven navigation.\n- `config/SupabaseClient.kt`: Supabase client initialization with Storage plugin.\n- `data/repositories/EventsRepository.kt`: Realtime events stream and `addNewEvent`.\n- `viewmodel/AuthViewModel.kt`: Auth state and sign-in/register/sign-out.\n- `viewmodel/EventViewModel.kt`: Event stream and image upload.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteamclassify%2Fhublink-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteamclassify%2Fhublink-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteamclassify%2Fhublink-app/lists"}