Skip to content

Commit 2266076

Browse files
authored
Merge pull request #604 from synonymdev/fix/all-warnings
fix: compiler warnings and code patterns
2 parents 528b028 + 055cba5 commit 2266076

163 files changed

Lines changed: 2099 additions & 2490 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/img/detekt.png

439 KB
Loading

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ google-services.json
1919
*.keystore
2020
!debug.keystore
2121
keystore.*
22-
!*.template
22+
!keystore.properties.template

AGENTS.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,12 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
162162
- ALWAYS run `./gradlew detekt` after code changes to check for new lint issues and fix accordingly
163163
- ALWAYS ask clarifying questions to ensure an optimal plan when encountering functional or technical uncertainties in requests
164164
- ALWAYS when fixing lint or test failures prefer to do the minimal amount of changes to fix the issues
165-
- USE single-line commit messages under 50 chars; use template format: `feat: add something new`
165+
- USE single-line commit messages under 50 chars; use conventional commit messages template format: `feat: add something new`
166166
- USE `git diff HEAD sourceFilePath` to diff an uncommitted file against the last commit
167+
- ALWAYS run `git status` to check ALL uncommitted changes after completing any code edits, then provide exactly 3 commit message suggestions covering the ENTIRE uncommitted diff
167168
- ALWAYS check existing code patterns before implementing new features
168169
- USE existing extensions and utilities rather than creating new ones
169-
- ALWAYS consider applying YAGNI (You Aren't Gonna Need It) principle for new code
170+
- ALWAYS consider applying YAGNI (You Ain't Gonna Need It) principle for new code
170171
- ALWAYS reuse existing constants
171172
- ALWAYS ensure a method exist before calling it
172173
- ALWAYS remove unused code after refactors
@@ -175,14 +176,17 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
175176
- ALWAYS acknowledge datastore async operations run synchronously in a suspend context
176177
- NEVER use `runBlocking` in suspend functions
177178
- ALWAYS pass the TAG as context to `Logger` calls, e.g. `Logger.debug("message", context = TAG)`
179+
- ALWAYS log errors at the final handling layer where the error is acted upon, not in intermediate layers that just propagate it
178180
- ALWAYS use the Result API instead of try-catch
179181
- NEVER wrap methods returning `Result<T>` in try-catch
180182
- PREFER to use `it` instead of explicit named parameters in lambdas e.g. `fn().onSuccess { log(it) }.onFailure { log(it) }`
181183
- NEVER inject ViewModels as dependencies - Only android activities and composable functions can use viewmodels
182184
- NEVER hardcode strings and always preserve string resources
183185
- ALWAYS localize in ViewModels using injected `@ApplicationContext`, e.g. `context.getString()`
184186
- ALWAYS use `remember` for expensive Compose computations
185-
- ALWAYS add modifiers to the last place in the argument list when calling `@Composable` functions
187+
- ALWAYS add modifiers to the last place in the argument list when calling composable functions
188+
- NEVER add parameters with default values BEFORE the `modifier` parameter in composable functions - modifier must be the FIRST optional parameter
189+
- ALWAYS prefer `VerticalSpacer`, `HorizontalSpacer`, `FillHeight` and `FillWidth` over `Spacer` when applicable
186190
- PREFER declaring small dependant classes, constants, interfaces or top-level functions in the same file with the core class where these are used
187191
- ALWAYS create data classes for state AFTER viewModel class in same file
188192
- ALWAYS return early where applicable, PREFER guard-like `if` conditions like `if (condition) return`
@@ -195,22 +199,23 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
195199
- ALWAYS be mindful of thread safety when working with mutable lists & state
196200
- ALWAYS split screen composables into parent accepting viewmodel + inner private child accepting state and callbacks `Content()`
197201
- ALWAYS name lambda parameters in a composable function using present tense, NEVER use past tense
198-
- ALWAYS list 3 suggested commit messages after implementation work for the entire set of uncommitted changes
199202
- NEVER use `wheneverBlocking` in unit test expression body functions wrapped in a `= test {}` lambda
200-
- ALWAYS wrap unit tests `setUp` methods mocking suspending calls with `runBlocking`, e.g `setUp() = runBlocking { }`
203+
- ALWAYS wrap unit tests `setUp` methods mocking suspending calls with `runBlocking`, e.g `setUp() = runBlocking {}`
201204
- ALWAYS add business logic to Repository layer via methods returning `Result<T>` and use it in ViewModels
202-
- ALWAYS use services to wrap RUST code exposed via bindings
203205
- ALWAYS order upstream architectural data flow this way: `UI -> ViewModel -> Repository -> RUST` and vice-versa for downstream
204206
- ALWAYS add new localizable string string resources in alphabetical order in `strings.xml`
205207
- NEVER add string resources for strings used only in dev settings screens and previews and never localize acronyms
206208
- ALWAYS use template in `.github/pull_request_template.md` for PR descriptions
207209
- ALWAYS wrap `ULong` numbers with `USat` in arithmetic operations, to guard against overflows
208-
- PREFER to use one-liners with `run { }` when applicable, e.g. `override fun someCall(value: String) = run { this.value = value }`
210+
- PREFER to use one-liners with `run {}` when applicable, e.g. `override fun someCall(value: String) = run { this.value = value }`
209211
- ALWAYS add imports instead of inline fully-qualified names
212+
- PREFER to place `@Suppress()` annotations at the narrowest possible scope
210213

211214
### Architecture Guidelines
212215

213216
- Use `LightningNodeService` to manage background notifications while the node is running
214217
- Use `LightningService` to wrap node's RUST APIs and manage the inner lifecycle of the node
215218
- Use `LightningRepo` to defining the business logic for the node operations, usually delegating to `LightningService`
216219
- Use `WakeNodeWorker` to manage the handling of remote notifications received via cloud messages
220+
- Use `*Services` to wrap rust library code exposed via bindings
221+
- Use CQRS pattern of Command + Handler like it's done in the `NotifyPaymentReceived` + `NotifyPaymentReceivedHandler` setup

README.md

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ This repository contains a **new native Android app** which is **not ready for p
1717

1818
#### 1. Firebase Configuration
1919

20-
Download `google-services.json` from the Firebase Console for each build flavor:
21-
- **Dev/Testnet**: Place in `app/` (default location)
22-
- **Mainnet**: Place in `app/src/mainnet/google-services.json`
20+
Download `google-services.json` from the Firebase Console for each of the following build flavor groups,:
21+
- dev/tnet/mainnetDebug: Place in `app/google-services.json`
22+
- mainnetRelease: Place in `app/src/mainnetRelease/google-services.json`
2323

2424
> **Note**: Each flavor requires its own Firebase project configuration. The mainnet flavor will fail to build without its dedicated `google-services.json` file.
2525
@@ -43,23 +43,24 @@ See also:
4343
- [bitkit-core android bindings](https://github.com/synonymdev/bitkit-core/tree/master/bindings/android#installation)
4444
- [vss-rust-client-ffi android bindings](https://github.com/synonymdev/vss-rust-client-ffi/tree/master/bindings/android#installation)
4545

46-
### Related Repositories
46+
### References
4747

48-
- [bitkit-ios](https://github.com/synonymdev/bitkit-ios) - Native iOS Bitkit app
49-
- [bitkit-core](https://github.com/synonymdev/bitkit-core) - Shared Core Rust library with FFI bindings
50-
- [ldk-node](https://github.com/synonymdev/ldk-node) - Fork of ldk-node
51-
- [vss-server](https://github.com/synonymdev/vss-server) - Versioned Storage Service backend
52-
- [vss-rust-client-ffi](https://github.com/synonymdev/vss-rust-client-ffi) - FFI bindings for vss-rust-client
53-
- [bitkit-e2e-tests](https://github.com/synonymdev/bitkit-e2e-tests) - End-to-end tests (WebdriverIO + Appium)
54-
- [bitkit-docker](https://github.com/synonymdev/bitkit-docker) - Docker setup for LNURL dev testing and local backend for integrations development
48+
- For LNURL dev testing see [bitkit-docker](https://github.com/synonymdev/bitkit-docker)
5549

5650
### Lint
5751

5852
This project uses detekt with default ktlint and compose-rules for android code linting.
5953

60-
Recommended Android Studio plugins:
61-
- EditorConfig
62-
- Detekt
54+
### IDE Plugins
55+
The following IDE plugins are recommended for development with Android Studio or IntelliJ IDEA:
56+
- [Compose Color Preview](https://plugins.jetbrains.com/plugin/21298-compose-color-preview)
57+
- [Compose Stability Analyzer](https://plugins.jetbrains.com/plugin/28767-compose-stability-analyzer)
58+
- [detekt](https://plugins.jetbrains.com/plugin/10761-detekt)
59+
<details>
60+
<summary>See screenshot on how to setup the Detekt plugin after installation.</summary>
61+
62+
![Detekt plugin setup][img_detekt]
63+
</details>
6364

6465
**Commands**
6566
```sh
@@ -112,16 +113,31 @@ The build config supports building 3 different apps for the 3 bitcoin networks (
112113
- `mainnet` flavour = mainnet
113114
- `tnet` flavour = testnet
114115

115-
### Build for Mainnet
116+
### Build for Internal Testing
116117

117-
To build the mainnet flavor:
118+
**Prerequisites**
119+
Setup the signing config:
120+
- Add the keystore file to root dir (i.e. `internal.keystore`)
121+
- Setup `keystore.properties` file in root dir (`cp keystore.properties.template keystore.properties`)
122+
123+
**Routine**
118124

125+
Increment `versionCode` and `versionName` in `app/build.gradle.kts`, then run:
119126
```sh
120-
./gradlew assembleMainnetDebug # debug build
121-
./gradlew assembleMainnetRelease # release build (requires signing config)
127+
./gradlew assembleDevRelease
128+
# ./gradlew assembleRelease # for all flavors
122129
```
123130

124-
> **Important**: Ensure `app/src/mainnet/google-services.json` exists before building. See [Firebase Configuration](#1-firebase-configuration).
131+
APK is generated in `app/build/outputs/apk/_flavor_/release`. (`_flavor_` can be any of 'dev', 'mainnet', 'tnet').
132+
Example for dev: `app/build/outputs/apk/dev/release`
133+
134+
### Build for Release
135+
136+
To build the mainnet flavor for release run:
137+
138+
```sh
139+
./gradlew assembleMainnetRelease
140+
```
125141

126142
### Build for E2E Testing
127143

@@ -152,24 +168,6 @@ By default, geoblocking checks via API are enabled. To disable at build time, us
152168
GEO=false E2E=true ./gradlew assembleDevRelease
153169
```
154170

155-
### Build for Release
156-
157-
**Prerequisites**
158-
Setup the signing config:
159-
- Add the keystore file to root dir (i.e. `release.keystore`)
160-
- Setup `keystore.properties` file in root dir (`cp keystore.properties.template keystore.properties`)
161-
162-
**Routine**
163-
164-
Increment `versionCode` and `versionName` in `app/build.gradle.kts`, then run:
165-
```sh
166-
./gradlew assembleDevRelease
167-
# ./gradlew assembleRelease # for all flavors
168-
```
169-
170-
APK is generated in `app/build/outputs/apk/_flavor_/release`. (`_flavor_` can be any of 'dev', 'mainnet', 'tnet').
171-
Example for dev: `app/build/outputs/apk/dev/release`
172-
173171
## Contributing
174172

175173
### AI Code Review with Claude
@@ -223,3 +221,5 @@ Destructive operations like `rm -rf`, `git commit`, and `git push` still require
223221

224222
This project is licensed under the MIT License.
225223
See the [LICENSE](./LICENSE) file for more details.
224+
225+
[img_detekt]: .github/img/detekt.png

app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import java.util.Properties
99
plugins {
1010
alias(libs.plugins.android.application)
1111
alias(libs.plugins.compose.compiler)
12+
alias(libs.plugins.compose.stability.analyzer)
1213
alias(libs.plugins.kotlin.android)
1314
alias(libs.plugins.kotlin.serialization)
1415
alias(libs.plugins.ksp)
@@ -218,6 +219,7 @@ dependencies {
218219
androidTestImplementation(platform(libs.compose.bom))
219220
implementation(libs.compose.material3)
220221
implementation(libs.compose.material.icons.extended)
222+
implementation(libs.compose.runtime.tracing)
221223
implementation(libs.compose.ui)
222224
implementation(libs.compose.ui.graphics)
223225
implementation(libs.compose.ui.tooling.preview)

0 commit comments

Comments
 (0)