Awesome
<img src="assets/logo.png" width="120" height="120"> <img align="right" src="assets/playstore.png" width="200" height="80">
Just an app with lame dad jokes content to fill up your day.
MVP
<img align="right" src="assets/demo.gif" width="40%"> This MVP version features:
- Feed walks you through the latest dad jokes,
- Browse back seen jokes & share your favorite ones,
- Notification to remind you up with latest available jokes,
- Light/ Dark theme based on preference.
Stacks
Foundation
- App Startup - Orchestrating single ContentProvider at startup.
- Coroutines - Performing asynchronous code with sequential manner.
- Dagger Hilt - The DI framework w/ Jetpack integration.
- DataStore - Preferences in nutshell with coroutines support.
- Flow - Reactive streams based on coroutines, just like Rx. But simpler.
- Fragment - The UI host.
- JavaPoet - Personal diff-state engine printer.
- Lifecycle - Android's component lifecycle teams up with coroutines.
- Navigation component - The key player for adopting single-activity architecture with ease.
- SQLDelight - ORM for SQLite database, Multiplatform. Also, try out its integration with Database Inspector.
- View Binding - Providing safe access to view.
- ViewModel - Presenter with its semi data persistence behavior.
- WorkManager - Background job scheduler. You should also try out its integration with WorkManager Inspector.
UI
- BottomSheetDialogFragment - As the name suggests.
- ConcatAdapter - Helping me group
ViewHolder
based on types in isolation. - ConstraintLayout - Helping me manage positioning & alignment with ease.
- Lottie - Providing animation asset.
- Material Components - Helping me present Material Design.
- MotionLayout - Animating view has never been easier.
- ViewPager2 - Personal option over
RecyclerView
when dealing snapping UX.
Internal
- LiveListAdapter <br/>
ListAdapter w/ every visible cell (
ViewHolder
) is reactive. Cell acts like observer of data they hold, so it will auto-refresh if their related data is updated.<br/> - RenderExecutor Processor <br/>
Processor for
RenderWith
annotation. Diff-state engine generator for rendering view component.
Remote
- Apollo GraphQL - Client for requesting GraphQL API, Multiplatform.
Testing
- Espresso - Android UI tests.
- Hilt Testing - For swapping production dependencies with test doubles.
- Truth - Assertion framework in tests by Google.
Health
- Firebase Crashlytics - Collecting crash report for production environment.
- LeakCanary (Debug) - Memory leak detector.
- StrictMode (Debug) - Tool for checking if any should-be-background operation is done on main thread. <br/>
MAD Scorecard
<img src="assets/mad_scorecard.png"> <br/> <br/> <br/>
<img align="left" width=50% src="assets/kmm.png">
Supports
Dads is ready to support multiplatform with the Clean Architecture concept for project structure (data
-domain
-presentation
).
<br/>
JVM, JS, or Native, He is just waiting your implementation of presentation part! <br/> <br/>
Architecture
Dads adopts MVVM with Unidirectional flow (UDF) pattern. <br/> <br/> Moreover, view components are rendered based on their related changed states only performed by diff-state engine, so the render operation is done more efficiently. <br/> <br/> <img src="assets/architecture.png">
Design Principles
- Elegant Objects (EO).
- O.L.I.D, where's the S?
- The Clean Architecture.
- Cursor-based pagination over offset-based.
Testing Principles
- Black-box/ behavior-driven testing with
UI
as the sole SUT (very recommended read and talk). - No mocking framework! Only fake type as test double, if required. <br/>
<img align="left" width="100" height="100" src="assets/graphql.png">
GraphQL Engine
Jokes are requested from proprietary GraphQL service, the Dads-Engine. Check it out 🔥 <br/> <br/>
How to run
- Since this project employs GraphQL stack, you need to download the schema first:
- Go to hosted GraphQL Playground,
- Open tab
SCHEMA
at the right side.DOWNLOAD
it, - Put the
schema.json
in directory:data/remote/src/commonMain/graphql/com/bael/dads/data/remote/
, - Or you can run this command as alternative.
./gradlew downloadApolloSchema --endpoint="https://dads-engine.herokuapp.com" --schema="data/remote/src/commonMain/graphql/com/bael/dads/data/remote/schema.json"
- Set
JWT
key inkeys.properties
file (located in project root folder):
JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHAiOiJEYWRzISIsInR5cGUiOiJVc2VyIn0.46oGvluHExsPIOS9d925RNYrk_Y9eke0Zm45ZbqjaXs
- Have fun!
Caveat
After went through How to run section but you still get a "Service issue" state, hit TRY AGAIN?
a couple of times until success. That's because I host data to the server with basic free plan - potato spec, well, it's just for research purpose anyway 😂.
Contributing
Let's get in touch if you're interested in contributing. Explain what's the issue, submit your PR via Fork.<br/> Also feel free to request features, or any kind of your support (join stargazers ⭐️ | treat me coffee 😁).
Those wonder what's next, check out my planned Roadmap by GitHub project board.