# CS:GO Matches ![Logo](/docs/logo.png) ![Unit tests](https://git.leomurca.xyz/leomurca/csgo-matches/actions/workflows/unit-tests.yml/badge.svg) **CSGO Matches** is a modern Android app that displays upcoming and live Counter-Strike: Global Offensive matches using the [PandaScore API](https://www.pandascore.co/). The app is built with Jetpack Compose, MVVM, and a layered architecture that blends principles from Clean Architecture and Layered Architecture for simplicity, scalability, and testability. ## ๐Ÿ“ธ Screenshots | Splash Screen | Match List | Match Details | |----------------------------------|--------------------------------|-----------------------------------| | ![Screenshot](./docs/splash.png) | ![Screenshot](./docs/home.png) | ![Screenshot](./docs/details.png) | ## โœจ Features - ๐Ÿ”„ Real-time list of upcoming and live CSGO matches - ๐Ÿ•’ Localized match time formatting (Hoje, Amanhรฃ, weekday in pt-BR) - ๐ŸŽฎ Team information and match time display - ๐Ÿ“ฑ Built with Jetpack Compose and Material 3 - ๐Ÿ” MVVM architecture for reactive UI state handling - ๐Ÿงฑ Clean + Layered architecture for maintainability - ๐Ÿ”ƒ **Pagination support** to load more matches as you scroll - ๐Ÿ” **Pull-to-refresh** on the home screen to manually refresh data - โœ… Unit tested with MockK and JUnit - โš™๏ธ CI pipeline to automatically run tests on push to main ## ๐Ÿš€ Getting Started ### โœ… Prerequisites - Android Studio Giraffe or newer - JDK 17 or higher - Git installed ### ๐Ÿ“ฅ Clone the Repository ```bash git clone https://git.leomurca.xyz/leomurca/csgo-matches.git cd csgo-matches ``` ### ๐Ÿ”‘ Configure API Access This project integrates with the PandaScore API, and requires two secrets to run: | Gradle Property | Description | Example | |-----------------|----------------------------------|-----------------------------------| | `API_BASE_URL` | Base URL of the API | `https://api.pandascore.co/csgo/` | | `ACCESS_TOKEN` | Your PandaScore API access token | `YOUR_API_KEY` | You must define these two properties in your local Gradle environment. Add the following lines to your global Gradle properties (`gradle.properties`): ```bash API_BASE_URL=https://api.pandascore.co/csgo/ ACCESS_TOKEN=your_actual_token_here ``` ### โ–ถ๏ธ Run the App - Open the project in Android Studio - Wait for Gradle sync to complete - Connect an Android device or launch an emulator - Click Run ## ๐Ÿงฑ Architecture Overview The architecture follows a hybrid approach: - ๐Ÿงฉ MVVM (Modelโ€“Viewโ€“ViewModel): Used to manage UI state with Compose and ViewModels. - ๐Ÿงฑ Layered Architecture: Presentation, domain, and data layers clearly separated. - ๐Ÿงผ Clean Architecture-inspired: The domain layer defines interfaces and models decoupled from frameworks (but no strict use case boundaries to avoid overengineering for this scope). ## ๐Ÿ“ Layer Breakdown | Layer | Responsibilities | |-----------------------|----------------------------------------------------------------------------------| | **UI (Presentation)** | Jetpack Compose UI, screen states, navigation, and ViewModels | | **Domain** | Appโ€™s business logic: pure models and repository interfaces | | **Data** | Implements repository interfaces, handles API calls, interceptors, DTOs, mappers | | **DI** | Centralized dependency injection configuration using Hilt | | **Utils** | Shared extension functions, helpers, and formatting logic | ## ๐Ÿ“‚ Folder Structure ```bash xyz.leomurca.csgomatches/ โ”œโ”€โ”€ data/ # Data layer: API, DTOs, mappers, remote implementations โ”‚ โ”œโ”€โ”€ mapper/ # DTO โ†” Domain model transformations โ”‚ โ”œโ”€โ”€ model/ # API response models (DTOs) โ”‚ โ”œโ”€โ”€ remote/ # Retrofit services, interceptors โ”‚ โ”œโ”€โ”€ repository/ # Implements domain repositories โ”‚ โ””โ”€โ”€ source/ # Data source abstractions โ”‚ โ”œโ”€โ”€ domain/ # Core business logic โ”‚ โ”œโ”€โ”€ model/ # Domain-level models (pure Kotlin) โ”‚ โ””โ”€โ”€ repository/ # Repository interfaces (contracts for data access) โ”‚ โ”œโ”€โ”€ ui/ # Compose UI and ViewModel layer โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (buttons, cards) โ”‚ โ”œโ”€โ”€ navigation/ # Navigation graph โ”‚ โ”œโ”€โ”€ screens/ # Individual screen UIs and ViewModels โ”‚ โ””โ”€โ”€ theme/ # Material theme, colors, typography โ”‚ โ”œโ”€โ”€ di/ # Hilt dependency injection modules โ”‚ โ”œโ”€โ”€ DispatchersModule.kt โ”‚ โ””โ”€โ”€ NetworkModule.kt โ”‚ โ”œโ”€โ”€ utils/ # Helper functions and extensions โ”‚ โ”œโ”€โ”€ CSGOApplication.kt # Custom Application class (Hilt entry point) โ””โ”€โ”€ MainActivity.kt # Main app entry point with Compose navigation ``` ## โš™๏ธ Tech Stack - Language: Kotlin - UI: Jetpack Compose - Architecture: MVVM + Layered/Clean mix - Networking: Retrofit + OkHttp - DI: Hilt - Async: Kotlin Coroutines + Flow - Testing: JUnit, MockK ## โœ… Testing & CI The project includes targeted unit tests focused on key areas like data mapping, repository behavior, and time formatting logic. **Test coverage includes:** - Mapping from API models to domain models - Remote data fetching logic - Repository integration - Date/time formatting for localized match display To ensure quality, a Forgejo Actions CI pipeline runs automatically on every push to main, executing unit tests in a Docker-based Android environment. This setup guarantees early detection of regressions and helps maintain stability as the project evolves.