RandomBoxd is a Compose Multiplatform project designed to fetch a random movie from a Letterboxd user's watchlists or custom lists. This app is built for Android and iOS devices. π±π¬
- Android (phones & tablets): Available now on Google Play.
- iOS (iPhone & iPad): Coming soon to the App Store.
- π² Fetch a random movie from a Letterboxd user's watchlist or custom lists.
- π± Supports Android and iOS platforms.
- π Seamless deep linking with the Letterboxd app.
- π Intuitive user search functionality.
- π·οΈ Stores and displays previously entered UserNames locally via Room, shown as tappable tags for quick reuse or deletion.
- β©βͺ Intersection & Union β Combine multiple users' watchlists and pick a random movie either from their shared movies (Intersection) or from the merged pool (Union).
- π Genre Filters β Narrow results to one or more genres at once. Works in both single-user and multi-user modes.
This project follows the Clean Architecture principles to ensure a scalable and maintainable codebase. For a detailed breakdown of layers, patterns, conventions, and technical decisions, see the Architecture Document.
-
/composeAppis for code that will be shared across your Compose Multiplatform applications.commonMaincontains code common for all targets.- Other folders include platform-specific code (e.g.,
iosMainfor iOS-specific code like CoreCrypto integration).
-
/iosAppcontains iOS applications.- Even if you're sharing UI with Compose Multiplatform, this folder is the entry point for the iOS app.
- This is also where you can add SwiftUI code if needed.
- Compose Multiplatform (CMP) - Shared logic for Android and iOS with Compose.
- Jetpack Compose - UI for Android.
- Ktor - Network requests.
- Coroutines & Flow - Asynchronous programming.
- Koin - Dependency Injection.
- Coil - Image loading.
- Room - Database.
- Ksoup - HTML parsing.
- Navigation Compose - Jetpack Compose navigation.
- Kotlinx Serialization - JSON serialization.
- Spotless - Code formatting.
- Junit5 - Unit testing.
- Turbine - State testing.
- Jacoco - Code coverage.
RandomBoxd is built with full localization support, allowing the app to be translated into any language.
- π³οΈ Uses Kotlin Multiplatform's localization tools for seamless translations.
- π Supports dynamic text updates based on user preferences.
- π Easily adaptable for different regions and languages.
RandomBoxd's codebase is tested with:
- π§ͺ JUnit5 for unit tests.
- π Turbine for verifying Kotlin Flow emissions and state changes.
- π Ktor Client Mock for mocking and testing network requests.
- π Jacoco to measure and ensure code coverage across the project.
RandomBoxd allows you to combine multiple users' watchlists by holding the Submit button or selecting multiple user tags.
From there, a single random movie is chosen based on two available modes:
- β© Intersection β Selects only movies that are present in every selected user's watchlist.
- βͺ Union β Combines all movies from the selected users' watchlists and randomly picks one from the full collection.
RandomBoxd lets you narrow your random pick to specific genres using the Genre button next to the search bar.
Select one or more genres and the app will only consider movies that match your selection:
- Single genre β e.g. only Horror movies from your watchlist.
- Multiple genres β combines genres so any matching movie can be picked.
- Reset anytime β clear the filter with one tap to go back to the full list.
Works seamlessly with both single-user and multi-user (Intersection & Union) modes.
-
Clone the repository:
git clone https://github.com/Nacchofer31/RandomBoxd.git
-
Open the project in Android Studio (latest version with CMP Plugin).
-
Run spotless commmands:
./gradlew :composeApp:spotlessApply
-
Generate jacoco reports:
./gradlew :composeApp:jacocoTestReport
-
Start selecting random movies from Letterboxd lists! ποΈ
Feel free to open issues or submit pull requests to improve the project. π οΈ
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
Enjoy RandomBoxd and never struggle to pick a movie again! π¬π











