{"id":13606293,"url":"https://github.com/LinX64/CoinCap","last_synced_at":"2025-04-12T08:30:52.046Z","repository":{"id":65297105,"uuid":"578953818","full_name":"LinX64/CoinCap","owner":"LinX64","description":"Best practice (Modularization) - built entirely with Jetpack Compose. It also includes CI/CD, Renovate, Detekt and version-catalog. This project is the most up-to-date Android project.","archived":false,"fork":false,"pushed_at":"2024-06-08T14:59:08.000Z","size":4383,"stargazers_count":69,"open_issues_count":13,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-08T15:15:35.515Z","etag":null,"topics":["android","coroutines-android","jetpack-compose","kotlin","modularization","version-catalog","workflow"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LinX64.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-16T09:39:15.000Z","updated_at":"2024-06-09T15:31:18.777Z","dependencies_parsed_at":"2023-02-17T09:46:15.125Z","dependency_job_id":"1ef7a00e-8574-4c33-a550-5dd1908c82eb","html_url":"https://github.com/LinX64/CoinCap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinX64%2FCoinCap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinX64%2FCoinCap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinX64%2FCoinCap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinX64%2FCoinCap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LinX64","download_url":"https://codeload.github.com/LinX64/CoinCap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248539779,"owners_count":21121231,"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","coroutines-android","jetpack-compose","kotlin","modularization","version-catalog","workflow"],"created_at":"2024-08-01T19:01:07.864Z","updated_at":"2025-04-12T08:30:47.039Z","avatar_url":"https://github.com/LinX64.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# CoinCap - (I'm not maintaining this project anymore)\n\nBest practice (Modularization) - built entirely with Jetpack Compose and cutting-edge libraries like\nCoroutines, Flow, Hilt, Coil, etc.\n\nThis project is using Material 3 components, as well as the Compose navigation library. It also has\nan integrated Static Analysis tool (Detekt) and CI/CD pipeline (Github Actions) + web scraping using a python script.\n\n### Libraries and Tools\n\n- Jetpack Compose\n- Hilt\n- Retrofit (with a deserializer for another API)\n- Coroutines\n- Coil\n- Detekt\n- GitHub Actions\n- Material 3\n- Compose Navigation\n\n#### CI/CD\n\n- I've used GitHub Actions, and Bitrise just to see different results from different platforms, and\n  so far, IMO, GitHub Actions is nicer, Bitrise already has everything but I'd like to have some\n  flexibility and write some scripts :)\n\n- There was an issue with the previous local rates API, from bonbast.com which I replaced that with\n  a new strategy. I've used a new script to scrap the data with Github Actions and store it in a\n  file called currencies.json. The script is available in the project.\n\n### Showcase\n\nhttps://user-images.githubusercontent.com/15968667/210910446-79249585-3c54-451f-a310-b32088a35313.mp4\n\n\u003cp\u003e\n\u003cimg src=\"https://i.imgur.com/4hQXpR2.png\" height=\"420\" /\u003e\n\u003cimg src=\"https://i.imgur.com/kZJbtow.png\" height=\"420\" /\u003e\n\u003cimg src=\"https://i.imgur.com/5cGryi7.png\" height=\"420\" /\u003e\n\u003cimg src=\"https://i.imgur.com/wMx9kOL.png\" height=\"420\" /\u003e\n\u003c/p\u003e\n\n### Architecture\n\nI've used the best practices from Google's official\nrepository [NowInAndroid](https://github.com/android/nowinandroid), and used Modularization to make\nthe app more scalable and maintainable.\n\n### Modules\n\n\u003cimg src=\"https://i.imgur.com/21DcyNY.png\" width=\"400\"\u003e\n\n### Features\n\n1. The logic behind searching is to get the data only after the last character is entered (using\n   `flatMapLatest()` flow operator).\n2. For the home screen, I am planning to get some data from the server for showing on the LineChart,\n   but for now, I am using dummy data.\n3. Unfortunately, the API doesn't provide the data for the `LineChart`, so I am using dummy data for\n   now.\n4. Iran (my home country) has been facing inflation for the last decade, and surprisingly, because\n   of protests and the lack of management, the inflation rate is increasing day by day. So, I took\n   the chance and put a logic for showing the rates in different currencies as **Local Currency**,\n   with a refresh policy between Saturday to Thursday, and the rates will be updated every 5\n   minutes. For Friday, the rates will be retrieved from the previous day.\n\n### Implementation\n\nThis section is for those who are interested in the implementation details.\n\n#### Home Screen\n\nI had to combine two flows into one to avoid unnecessary network calls and extra logics inside\nviews. So here is how I did it:\n\n\u003cimg src=\"https://i.imgur.com/c4rrVzx.jpg\" width=\"520\"\u003e\n\nThe implementation is pretty simple. I am using the `combine` operator to combine the two flows into\none. The `combine` operator will emit a new [Rate] model after multiplying the two values. The logic\nand code is available in\nthe [GetRatesUseCaseImpl](https://github.com/LinX64/CoinCap/blob/master/core/data/src/main/java/com/client/data/repository/foreignRates/RatesRepositoryImpl.kt)\nclass.\n\n#### API calls and deserialization\n\nI am using Retrofit for making API calls, and I am using a custom deserializer for the local\ncurrency API. The problem that I faced at first was that the original API was not free so I had to\nuse an already made API instead. Another problem was that the API was returning the data in a\ndifferent format, something like this format:\n\n````\n{\n  \"usd\": {\n    \"sell\": 43000,\n    \"buy\": 42900\n  },\n  \"eur\": {\n    \"sell\": 45870,\n    \"buy\": 45720\n  }\n}\n````\n\nIt was pretty hard to deserialize the data, so I had to write a custom deserializer for it. The\ndeserializer is basically converting all those three objects into a list of [LocalRate] objects.\nHere you can find the\ndeserializer: [CurrencyDeserializer](https://github.com/LinX64/CoinCap/blob/master/core/data/src/main/java/com/client/data/util/CurrencyDeserializer.kt)\n\nI am sure this is one of the major problems that all Android developers might face while\nusing `GSON` and `Retrofit`, so I hope this will help you.\n\n### API\n\nFor this project, I am\nusing [CoinCap API](https://docs.coincap.io/#ee30bea9-bb6b-469d-958a-d3e35d442d7a) for rates, as\nwell as\n[This API](https://bonbast-api.deta.dev/) for live Iranian exchange rates.\n\nAlso, I am using https://coinicons-api.vercel.app/api/icon/ for getting the icons of the coins.\n\n### Continuous Integration\n\nThe project is using GitHub Actions to build and test the app on every push and pull request on two\ndevices. Also, it is using Renovate to keep the dependencies up to date.\n\n### Static Code Analysis\n\nThe project is using Detekt for static code analysis, and it is using GitHub Actions to run the\nanalysis on every push and pull request.\n\nI also used Detekt formatter to format the code automatically which is somehow a wrapper for ktLint\nas well.\n\nPlease see: https://detekt.dev/docs/rules/formatting\n\n### TODO\n\n- Add Offline first support\n- Unit Tests\n- Get data from Server for LineChart\n- Add more features\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLinX64%2FCoinCap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLinX64%2FCoinCap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLinX64%2FCoinCap/lists"}