An Android app that displays Counter-Strike: Global Offensive (CS:GO) matches from multiple global tournaments.
Find a file
Leonardo Murça a7c31bc48b
All checks were successful
Android Unit Tests / tests (push) Successful in 7m6s
refactor: extract number to a constant
2025-07-20 16:57:15 -03:00
.forgejo/workflows ci: fix ci 2025-07-19 23:09:00 -03:00
.idea feat: format ScheduleBadge correctly based on local time zone 2025-07-18 18:08:42 -03:00
app refactor: extract number to a constant 2025-07-20 16:57:15 -03:00
docs docs: update README.md 2025-07-20 16:34:04 -03:00
gradle test: add unit tests for MatchRemoteDataSourceImpl 2025-07-19 16:23:23 -03:00
.gitignore feat: add app icon launcher 2025-07-17 12:55:05 -03:00
build.gradle.kts feat: add network, dto, mapping and repository initial setup 2025-07-17 21:15:36 -03:00
gradle.properties Initial commit 2025-07-17 10:52:21 -03:00
gradlew Initial commit 2025-07-17 10:52:21 -03:00
gradlew.bat Initial commit 2025-07-17 10:52:21 -03:00
README.md docs: add features section to README.md 2025-07-20 16:39:21 -03:00
settings.gradle.kts Initial commit 2025-07-17 10:52:21 -03:00

CS:GO Matches

Logo

Unit tests

CSGO Matches is a modern Android app that displays upcoming and live Counter-Strike: Global Offensive matches using the PandaScore API. 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 Screenshot Screenshot

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

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):

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 (ModelViewViewModel): 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 Apps 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

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.