Evently is an Android app for discovering concerts, sports, theatre and other live events, built with Jetpack Compose on top of the Ticketmaster Discovery API. Browse what's coming up, filter by category, search, and save events to a favorites list that works offline.
- Discover: a featured event and an upcoming carousel, filterable by Music, Sports, Arts & Theatre, Film and more
- Search: keyword search with infinite scrolling results
- Event details: date and time, venue with Open in Maps, prices, line-up, organizer notes and seat map
- Favorites: save events locally with Room; they stay available offline and update instantly
- Share and buy: share an event through the Android share sheet or open Ticketmaster to get tickets
- Considered states: shimmer placeholders while loading, clear messages for no connection or an invalid API key, and retry
| Area | Libraries |
|---|---|
| UI | Jetpack Compose, Material 3, Navigation Compose (type-safe routes), Coil |
| State | ViewModel, Kotlin Coroutines and StateFlow, Paging 3 |
| Data | Retrofit, OkHttp, kotlinx.serialization, Room |
| DI | Hilt |
| Build | Gradle version catalog, KSP, R8 |
| Testing | JUnit 4, kotlinx-coroutines-test, Turbine, MockWebServer, paging-testing |
The app follows a layered architecture with a unidirectional data flow:
flowchart LR
subgraph presentation
UI[Compose screens] -->|events| VM[ViewModels]
VM -->|UI state as StateFlow| UI
end
subgraph domain
Repo[[EventRepository]]
Model[Event, EventQuery]
end
subgraph data
Impl[EventRepositoryImpl] --> API[Ticketmaster API<br/>DTOs]
Impl --> DB[(Room<br/>favorites)]
end
VM --> Repo
Impl -. implements .-> Repo
- Network DTOs, Room entities and domain models are separate types joined by mappers, so missing API fields never crash the app and the database schema doesn't depend on the API's JSON shape.
- Repositories return
Result, so screens can tell "no events" apart from "no connection". - Each screen has its own ViewModel exposing a single immutable UI state. Screens are split into a stateful
*Routeand a stateless*Screen, which keeps them previewable.
app/src/main/java/com/myth/evently
├── data/ remote (Retrofit + DTOs), local (Room), mappers, repository
├── di/ Hilt modules
├── domain/ models and repository interfaces
├── presentation/ home, results, detail, favorites, navigation, shared components
└── ui/theme/ colors, typography, shapes
- Android Studio (recent stable) with JDK 17 or newer
- A free Ticketmaster API key from the Ticketmaster Developer Portal
-
Clone the repository:
git clone https://github.com/MichaelGift/Event-Finder-App.git
-
Add your key to
local.propertiesin the project root. This file is git-ignored, so the key never reaches the repository:TICKETMASTER_API_KEY=your_consumer_keyThe build also reads
TICKETMASTER_API_KEYfrom the environment, which is how CI supplies it. -
Open the project in Android Studio and run the
appconfiguration on a device or emulator (Android 8.0+).
./gradlew testDebugUnitTest # unit tests
./gradlew lintDebug # Android lint
./gradlew assembleDebug # debug APKThe unit tests cover the API-to-domain mappers, the repository (against a local MockWebServer), the ViewModels and the paging source. They don't need an API key.
GitHub Actions runs the unit tests, lint and a debug build on every push to master and on
every pull request. Test reports, the lint report and the debug APK are uploaded as workflow artifacts.
To build a working APK in CI, add the key under Settings → Secrets and variables → Actions as a repository
secret named TICKETMASTER_API_KEY.
Pushing a version tag publishes a signed APK to GitHub Releases through the release workflow:
git tag v1.2.0
git push origin v1.2.0The workflow checks that the tag points to a commit on master, runs the unit tests, then builds and signs the
release APK. It verifies the signature and creates a release with notes generated from the commits since the
previous tag.
- Versioning: the tag sets
versionName(v1.2.0→1.2.0).versionCodeis the workflow's run number, so it always increases. - Pre-releases: tags with a suffix, such as
v1.3.0-beta.1, are published as pre-releases. - Signing: the keystore comes from four repository secrets:
KEYSTORE_BASE64(the output ofbase64 -w0 release.jks),KEYSTORE_PASSWORD,KEY_ALIASandKEY_PASSWORD. Local release builds without these stay unsigned.
Contributions are welcome, whether a bug report, an idea or a pull request.
- Open an issue first for anything beyond a small fix, so the approach can be agreed before you write code.
- Fork the repository and create a branch from
master(for examplefeature/venue-searchorfix/empty-results). - Keep changes focused, follow the existing code style (Kotlin coding conventions), and add or update tests for behaviour you change.
- Make sure
./gradlew testDebugUnitTest lintDebugpasses locally. - Open a pull request describing what changed and why. Include screenshots for UI changes.
Please follow the Code of Conduct in all project spaces.
Evently is released under the MIT License.
Event data and images are provided by the Ticketmaster Discovery API and remain the property of their owners. This project is not affiliated with or endorsed by Ticketmaster. Use of the API is subject to the Ticketmaster Terms of Use.



