{"id":28174003,"url":"https://github.com/mshdabiola/hydraulicapp","last_synced_at":"2025-05-15T21:15:27.447Z","repository":{"id":239164169,"uuid":"798743418","full_name":"mshdabiola/HydraulicApp","owner":"mshdabiola","description":"Hydraulic is a template","archived":false,"fork":false,"pushed_at":"2025-05-10T15:42:54.000Z","size":24433,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-05-10T16:19:15.299Z","etag":null,"topics":["android","compose-multiplatform","datastores","desktop","kotlin-multiplatform","linux","macos","room-database","windows"],"latest_commit_sha":null,"homepage":"https://mshdabiola.github.io/Hydraulic/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mshdabiola.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-10T11:28:07.000Z","updated_at":"2025-05-10T15:42:56.000Z","dependencies_parsed_at":"2024-06-10T05:24:09.374Z","dependency_job_id":"b754cff4-7613-45cb-abc9-780c654bda44","html_url":"https://github.com/mshdabiola/HydraulicApp","commit_stats":null,"previous_names":["mshdabiola/hydraulic","mshdabiola/hydraulicapp"],"tags_count":71,"template":true,"template_full_name":"mshdabiola/SkeletonMultiplatform","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mshdabiola%2FHydraulicApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mshdabiola%2FHydraulicApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mshdabiola%2FHydraulicApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mshdabiola%2FHydraulicApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mshdabiola","download_url":"https://codeload.github.com/mshdabiola/HydraulicApp/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254422778,"owners_count":22068682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose-multiplatform","datastores","desktop","kotlin-multiplatform","linux","macos","room-database","windows"],"created_at":"2025-05-15T21:14:37.511Z","updated_at":"2025-05-15T21:15:27.425Z","avatar_url":"https://github.com/mshdabiola.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\n\u003cp align=\"center\"\u003e\n \u003ca\u003e\n  \u003cimg alt=\"Kotlin\" src=\"https://img.shields.io/badge/Kotlin-Multiplatform-%237f52ff?logo=kotlin\u0026style=for-the-badge\"/\u003e\n\u003c/a\u003e\n  \u003cimg alt=\"Jetpack Compose\" src=\"https://img.shields.io/static/v1?style=for-the-badge\u0026message=Jetpack+Compose\u0026color=4285F4\u0026logo=Jetpack+Compose\u0026logoColor=FFFFFF\u0026label=\"/\u003e \n    \u003cimg alt=\"material\" src=\"https://custom-icon-badges.demolab.com/badge/material%20you-lightblue?style=for-the-badge\u0026logoColor=333\u0026logo=material-you\"/\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n \u003ca href=\"\"\u003e\n\u003cimg src=\"https://tokei.rs/b1/github/mshdabiola/hydraulicapp?category=code\u0026color=orange\u0026style=for-the-badge\" alt=\"\"/\u003e\n\u003c/a\u003e\n    \u003ca href=\"https://github.com/mshdabiola/hydraulicapp/actions\"\u003e\n  \u003cimg alt=\"GitHub commits since tagged version (branch)\" src=\"https://img.shields.io/github/commits-since/mshdabiola/hydraulicapp/1.0.0?color=palegreen\u0026label=Commits\u0026style=for-the-badge\"\u003e\n  \u003cimg alt=\"GitHub code size in bytes\" src=\"https://img.shields.io/github/languages/code-size/mshdabiola/hydraulicapp?style=for-the-badge\u0026color=37ABB5\"\u003e\n  \u003cimg src=\"https://wakatime.com/badge/user/8e707c95-01e6-41d3-a760-223960f0cdf7.svg?style=for-the-badge\" alt=\"\"/\u003e\n\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://hits.sh/github.com/mshdabiola/hydraulicapp/\"\u003e\n      \u003cimg alt=\"Hits\" src=\"https://hits.sh/github.com/mshdabiola/hydraulicapp.svg?style=for-the-badge\u0026label=Views\u0026extraCount=7500\u0026color=ff3f6f\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/mshdabiola/hydraulicapp/releases\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/downloads/mshdabiola/hydraulicapp/total?color=orange\u0026style=for-the-badge\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/mshdabiola/hydraulicapp/stargazers\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/stars/mshdabiola/hydraulicapp?color=ffff00\u0026style=for-the-badge\"/\u003e\n  \u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/mshdabiola/hydraulicapp/releases/latest\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/v/release/mshdabiola/hydraulicapp?color=purple\u0026include_prereleases\u0026logo=github\u0026style=for-the-badge\"/\u003e\n  \u003c/a\u003e\n\n[//]: # (   \u003ca href=\"https://play.google.com/store/apps/details?id=ru.tech.hydraulicshrinker\"\u003e)\n\n[//]: # (      \u003cimg src=\"https://img.shields.io/endpoint?color=purple\u0026logo=google-play\u0026style=for-the-badge\u0026label=Play%20store\u0026url=https%3A%2F%2Fplay.cuzi.workers.dev%2Fplay%3Fi%3Dru.tech.hydraulicshrinker%26l%3DAndroid%26m%3D%24version\"/\u003e)\n\n[//]: # (  \u003c/a\u003e)\n\n[//]: # (  \u003ca href=\"https://f-droid.org/packages/ru.tech.hydraulicshrinker\"\u003e)\n\n[//]: # (      \u003cimg src=\"https://img.shields.io/f-droid/v/ru.tech.hydraulicshrinker?color=purple\u0026include_prereleases\u0026logo=FDROID\u0026style=for-the-badge\"/\u003e)\n\u003c/p\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://example.com\"\u003e\u003cimg alt=\"Google Play\" src=\"./fastlane/metadata/android/en-US/images/buttons/gplay.svg\" height=\"60\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://f-droid.org/packages/ru.tech.hydraulicshrinker\"\u003e\u003cimg alt=\"F-Droid\" src=\"./fastlane/metadata/android/en-US/images/buttons/fdroid.svg\" height=\"60\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/mshdabiola/hydraulicapp/releases/latest\"\u003e\u003cimg alt=\"GitHub\" src=\"./fastlane/metadata/android/en-US/images/buttons/github.svg\" height=\"60\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://hydraulicapp-desktop.onrender.com\"\u003e\u003cimg alt=\"Desktop Download\" src=\"./fastlane/metadata/android/en-US/images/buttons/desktop.svg\" height=\"60\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://hydraulicapp.onrender.com\"\u003e\u003cimg alt=\"HydraulicApp Online\" src=\"./fastlane/metadata/android/en-US/images/buttons/online.svg\" height=\"60\"/\u003e\u003c/a\u003e\n   \n\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cimg src=\"./fastlane/metadata/android/en-US/images/icon.png\" width=\"40%\"  alt=\"\"/\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e \n     \u003ch1\u003eHydraulicApp Compose Multiplatform Template\u003c/h1\u003e\n\u003c/div\u003e\n\n\u003cdiv style=\"text-align: center;\"\u003e\nhydraulicapp is a compose multiplatform template. that use note app as an example. it is multi-module architecture. \n\u003c/div\u003e\n\n\n## Screenshot\n\n### Phone\n\n\u003cp style=\"text-align: center;\"\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/1.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/2.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/3.png\" width=\"30%\"  alt=\"\"/\u003e\n\u003c/p\u003e\n\n### Desktop\n\n\u003cp style=\"text-align: center;\"\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/desktopScreenshots/1.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/desktopScreenshots/2.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/desktopScreenshots/3.png\" width=\"30%\"  alt=\"\"/\u003e\n\u003c/p\u003e\n\n### Web\n\n\u003cp style=\"text-align: center;\"\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/webScreenshots/1.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/webScreenshots/2.png\" width=\"30%\"  alt=\"\"/\u003e\n    \u003cimg src=\"./fastlane/metadata/android/en-US/images/webScreenshots/3.png\" width=\"30%\"  alt=\"\"/\u003e\n\u003c/p\u003e\n\n## Features\n\n- Dark mode theme\n- Change theme\n\n  \u003csummary\u003eAvailable filters\u003c/summary\u003e\n  \u003cbr\u003e\n\n# Tech stack \u0026 Open-source libraries\n\n- Minimum SDK level 21\n\n- [Kotlin](https://kotlinlang.org/) based\n\n\n- [Dynamic Theme](https://github.com/mshdabiola/DynamicTheme) - library, which allows you to easily\n  implement custom color theming.\n\n- [Coroutines](https://github.com/Kotlin/kotlinx.coroutines) for asynchronous work.\n\n- [Flow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/)\n  to emit values from data layer reactively.\n\n- [Koin](https://github.com/InsertKoinIO/koin) for dependency injection.\n\n- [Coil](https://github.com/coil-kt/coil) for loading images.\n\n- Jetpack\n\n    - [Compose](https://developer.android.com/jetpack/compose) - Modern Declarative UI style\n      framework based on composable functions.\n\n    - [Material You Kit](https://developer.android.com/jetpack/androidx/releases/compose-material3) -\n      Material 3 powerful UI components.\n\n    - [Room](https://developer.android.com/jetpack/androidx/releases/room) Constructs Database by providing an abstraction layer over SQLite to allow fluent database access.\n\n    - [Data Store](https://developer.android.com/jetpack/androidx/releases/datastore) - Store data\n      asynchronously, consistently, and transactionally.\n\n    - [Lifecycle](https://developer.android.com/jetpack/androidx/releases/lifecycle) - Observe\n      Android lifecycles and handle UI states upon the lifecycle changes.\n  \n- [Turbine](https://github.com/cashapp/turbine) - A small testing library for kotlinx.coroutines Flow.\n\n- [Timber](https://github.com/JakeWharton/timber) - A logger with a small, extensible API.\n\n- [ksp](https://github.com/google/ksp): Kotlin Symbol Processing API.\n\n- Architecture\n    - MVVM Architecture (Compose - ViewModel - Model)\n    - Repository Pattern\n    - This project use android modularization. You can find full graph [FULLGRAPH](FULLGRAPH.md)\n      \n\n## Build\n\nThis project utilizes Kotlin Multiplatform to target Android, Desktop, and WebAssembly (WASM).\nAndroid has two build variants: **GooglePlay** and **FossReliant**. To build and run the project on\neach platform, follow the instructions below:\n\n### Android\n\n#### GooglePlay Variant\n\n1. Open the project in Android Studio.\n2. Select the **GooglePlay** build variant.\n3. Connect an Android device or start an emulator.\n4. Run the `app` module. This will build an APK with Google Play dependencies and install it on your\n   device or emulator.\n\n#### FossReliant Variant\n\n1. Open the project in Android Studio.\n2. Select the **FossReliant** build variant.\n3. Connect an Android device or start an emulator.\n4. Run the `app` module. This will build an APK without Google Play dependencies, relying on FOSS\n   alternatives, and install it on your device or emulator.\n\n### Desktop\n\nRun the following command to build the desktop application:\n\n```bash\n./gradlew app:run\n```\n\nThis will run an executable file on your operating system (Windows, macOS, or Linux).\n\n### Web\n\nRun the following command to build the web application:\n\n```bash\n./gradlew wasmJsBrowserRun -t\n```\n\nThis will start a development server that serves the web application. Open the provided URL in your\nbrowser to access the application.\n\n**Note:** You may need to install Node.js and Yarn for the web build to work correctly.\n\n## Release\n\nThis project offers releases for Android, Desktop, and Web. Below are instructions for releasing the\napplication on each platform.\n\n### Android\n\n#### GooglePlay Variant\n\nTo release the GooglePlay variant, follow these steps:\n\nBuild the release APK using the following Gradle command:\n\n```bash\n./gradlew assembleGooglePlayRelease\n```\n\nUpload the signed APK to the Google Play Console.\n\n#### FossReliant Variant\n\nTo release the FossReliant variant, follow these steps:\n\nBuild the release APK using the following Gradle command:\n\n```bash\n./gradlew assembleFossReliantRelease\n```\n\nDistribute the APK through your preferred channels (e.g., GitHub Releases, F-Droid).\n\n### Desktop\n\nThis project leverages HydraulicApp Conveyor for packaging and distributing the Desktop application.\nHydraulicApp Conveyor simplifies the creation of installers and distributable packages across various\noperating systems (Windows, macOS, Linux).\n\n1. Install hydraulic conveyor at [Hydraulic](https://downloads.hydraulic.dev/)\n\n2. Build the release executable using the following Gradle command:\n\n```bash\nconveyor make app\n```\n\n3. To create site for the all desktop platform\n\n```bash\nconveyor make site\n```\n\n### Web\n\nTo release the Web application, follow these steps:\n\nBuild the release version of the web application using the following Gradle command:\n\n```bash\n./gradlew wasmJsBrowserDistribution\n```\n\nDeploy the built files to your web server or hosting provider.\n\n## Testing\n\n### JVM Tests\n\nThis project includes a comprehensive suite of JVM tests to ensure the correctness and reliability\nof the core logic and functionality. These tests are written using JvmTest and cover various aspects\nof the application, including:\n\n* **Unit tests:** Verify the behavior of individual components and functions in isolation.\n* **Integration tests:** Test the interaction between different modules or components of the system.\n* **Data layer tests:** Validate data access, persistence, and retrieval operations.\n* **Business logic tests:**  Ensure the correct implementation of business rules and workflows.\n\n**Running Tests**\n\nTo run the JVM tests, you can use the following Gradle command:\n\n```bash\n./gradlew jvmTest\n```\n\n### Screenshot Test\n\nCompose Screenshot Testing is an essential part of ensuring UI quality. A screenshot test captures\nan image of a Composable function or a section of your app's UI and compares it to a previously\nsaved reference image, known as a \"golden\" or \"baseline\" image. This ensures that UI changes don't\nunintentionally introduce visual regressions.\n\n**Compose ScreenshotTest and Gradle Tasks**\n\nCompose screenshot testing can be seamlessly integrated with the Paparazzi library, providing\nautomated image comparisons. Paparazzi offers the following useful Gradle tasks:\n\n- `validateFossReliantDebugScreenshotTest`: Executes all screenshot tests, comparing captured images\n  with the baseline images. This process helps detect any visual discrepancies introduced by code\n  changes.\n- `updateFossReliantDebugScreenshotTest`: Generates new baseline images. Use this command after\n  intentionally modifying the UI and manually verifying the correctness of the new visuals. The\n  newly captured screenshots then become the new baseline for future comparisons.\n- `testFossReliantDebugScreenshotTest`: Creates comparison images highlighting the differences\n  between failed tests and the baseline images. These images aid in pinpointing visual\n  discrepancies, simplifying debugging efforts.\n\n## Performance\n\n### Benchmarks\n\nWe utilize benchmarking tools to measure the performance of key operations in our application. This\nhelps identify potential bottlenecks and areas for optimization. Benchmarks are focused on critical\naspects, such as UI rendering, data processing, and network operations, ensuring a smooth and\nresponsive user experience.\n\n### Baseline Profile\n\nBaseline Profiles are integrated into our build process to enhance app startup time and reduce\ninitial rendering latency. These profiles provide guidance to the Android Runtime (ART) for\npre-compiling frequently used code paths, leading to faster loading times and improved overall\nperformance.\n\n\n```bash\n./gradlew generateReleaseBaselineProfile\n```\n\n### Compose Compiler Metrics\n\nWe leverage Compose Compiler Metrics to monitor and analyze the performance of our Compose UI.\nMetrics like recomposition counts and skippability rates help identify potential areas for\noptimization and ensure efficient UI rendering. This proactive approach ensures that our Compose UI\nremains performant and responsive as the application evolves.\n\n\n```bash\n./gradlew assembleDebug -PenableComposeCompilerMetrics=true -PenableComposeCompilerReports=true\n```\n\n## Find this repository useful?\n\nSupport it by joining **[stargazers](https://github.com/mshdabiola/hydraulicapp/stargazers)** for this\nrepository. :star: \u003cbr\u003e\nAnd **[follow](https://github.com/mshdabiola)** me for my next creations! 🤩\n\n## Star History\n\n\u003cdiv align=\"center\"\u003e\n\u003ca href=\"https://star-history.com/#mshdabiola/hydraulicapp\u0026Date\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=mshdabiola/hydraulicapp\u0026type=Date\u0026theme=dark\" /\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=mshdabiola/hydraulicapp\u0026type=Date\" /\u003e\n    \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=mshdabiola/hydraulicapp\u0026type=Date\" /\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n![Alt](https://repobeats.axiom.co/api/embed/a0893eb63066333a921a4197172ab150fe896a37.svg \"Repobeats analytics image\")\n\u003c/div\u003e\n\n## Contributors\n\n\u003ca href=\"https://github.com/mshdabiola/hydraulicapp/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=mshdabiola/hydraulicapp\" /\u003e\n\u003c/a\u003e\n\n\n# License\n\n**HydraulicApp** is distributed under the terms of the GNU License (Version 2.0). See the\n[license](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmshdabiola%2Fhydraulicapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmshdabiola%2Fhydraulicapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmshdabiola%2Fhydraulicapp/lists"}