mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
feat(sdk-android): snapshot property delegate + feature-scoped files + screen fix (#34)
* rename web to inspect ui * feat(sdk-android): add camelToSnakeCase conversion * feat(sdk-android): add snapshot() property delegate with tests * feat(folio): add feature-scoped sanderling snapshot objects * refactor(folio): slim FolioApplication to snapshot object references * fix(folio): rename route snapshot to screen, update spec.ts
This commit is contained in:
51 files changed
+297
-84
No files matched your search
@@ -3,14 +3,10 @@ package app.folio
|
||||
import android.app.Application
|
||||
import app.folio.data.AndroidLedgerContext
|
||||
import app.folio.data.Repository
|
||||
import app.folio.data.TxnType
|
||||
import app.folio.feature.account.AddAccountUiState
|
||||
import app.folio.feature.auth.LoginUiState
|
||||
import app.folio.feature.ledger.AddTransactionUiState
|
||||
import app.folio.navigation.Navigator
|
||||
import app.folio.navigation.Route
|
||||
import app.folio.platform.balanceOf
|
||||
import app.folio.platform.signedAmount
|
||||
import app.folio.sanderling.AccountSnapshots
|
||||
import app.folio.sanderling.AuthSnapshots
|
||||
import app.folio.sanderling.LedgerSnapshots
|
||||
import app.folio.sanderling.NavigationSnapshots
|
||||
import dev.sanderling.sdk.Sanderling
|
||||
|
||||
class FolioApplication : Application() {
|
||||
@@ -19,75 +15,9 @@ class FolioApplication : Application() {
|
||||
AndroidLedgerContext.context = applicationContext
|
||||
Repository.init()
|
||||
Sanderling.start(this)
|
||||
Sanderling.extract("logged_in") { Repository.session.value != null }
|
||||
Sanderling.extract("account_count") { Repository.accounts.value.size }
|
||||
Sanderling.extract("total_balance") { balanceOf(Repository.transactions.value) }
|
||||
Sanderling.extract("route") {
|
||||
when (Navigator.current.value) {
|
||||
Route.Login -> "login"
|
||||
Route.Home -> "home"
|
||||
Route.AddAccount -> "add-account"
|
||||
is Route.Ledger -> "ledger"
|
||||
is Route.AddTransaction -> "add-transaction"
|
||||
}
|
||||
}
|
||||
Sanderling.extract("auth_status") {
|
||||
if (Repository.session.value != null) "logged-in" else "logged-out"
|
||||
}
|
||||
Sanderling.extract("accounts") {
|
||||
val txns = Repository.transactions.value
|
||||
Repository.accounts.value.map { a ->
|
||||
val rows = txns.filter { it.accountId == a.id }
|
||||
mapOf(
|
||||
"id" to a.id,
|
||||
"name" to a.name,
|
||||
"balance" to balanceOf(rows),
|
||||
"txnCount" to rows.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
Sanderling.extract("active_account_id") {
|
||||
when (val r = Navigator.current.value) {
|
||||
is Route.Ledger -> r.accountId
|
||||
is Route.AddTransaction -> r.accountId
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
Sanderling.extract("ledger_rows") {
|
||||
val active = when (val r = Navigator.current.value) {
|
||||
is Route.Ledger -> r.accountId
|
||||
is Route.AddTransaction -> r.accountId
|
||||
else -> null
|
||||
}
|
||||
if (active == null) emptyList()
|
||||
else Repository.transactions.value
|
||||
.filter { it.accountId == active }
|
||||
.map {
|
||||
mapOf(
|
||||
"id" to it.id,
|
||||
"accountId" to it.accountId,
|
||||
"type" to if (it.type == TxnType.credit) "credit" else "debit",
|
||||
"amount" to it.amount,
|
||||
"signed" to signedAmount(it),
|
||||
)
|
||||
}
|
||||
}
|
||||
Sanderling.extract("ledger_balance") {
|
||||
val active = when (val r = Navigator.current.value) {
|
||||
is Route.Ledger -> r.accountId
|
||||
is Route.AddTransaction -> r.accountId
|
||||
else -> null
|
||||
}
|
||||
if (active == null) 0L
|
||||
else balanceOf(Repository.transactions.value.filter { it.accountId == active })
|
||||
}
|
||||
Sanderling.extract("focused_input") { FocusTracker.current.value }
|
||||
Sanderling.extract("txn_form_type") { AddTransactionUiState.txnFormType.value }
|
||||
Sanderling.extract("txn_form_account_id") {
|
||||
(Navigator.current.value as? Route.AddTransaction)?.accountId
|
||||
}
|
||||
Sanderling.extract("login_error") { LoginUiState.loginError.value }
|
||||
Sanderling.extract("add_account_error") { AddAccountUiState.addAccountError.value }
|
||||
Sanderling.extract("txn_error") { AddTransactionUiState.txnError.value }
|
||||
AuthSnapshots
|
||||
AccountSnapshots
|
||||
LedgerSnapshots
|
||||
NavigationSnapshots
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package app.folio.sanderling
|
||||
|
||||
import app.folio.data.Repository
|
||||
import app.folio.feature.account.AddAccountUiState
|
||||
import app.folio.platform.balanceOf
|
||||
import dev.sanderling.sdk.Sanderling
|
||||
|
||||
object AccountSnapshots {
|
||||
val accountCount by Sanderling.snapshot { Repository.accounts.value.size }
|
||||
val totalBalance by Sanderling.snapshot { balanceOf(Repository.transactions.value) }
|
||||
val accounts by Sanderling.snapshot {
|
||||
val txns = Repository.transactions.value
|
||||
Repository.accounts.value.map { a ->
|
||||
val rows = txns.filter { it.accountId == a.id }
|
||||
mapOf("id" to a.id, "name" to a.name, "balance" to balanceOf(rows), "txnCount" to rows.size)
|
||||
}
|
||||
}
|
||||
val addAccountError by Sanderling.snapshot { AddAccountUiState.addAccountError.value }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package app.folio.sanderling
|
||||
|
||||
import app.folio.data.Repository
|
||||
import app.folio.feature.auth.LoginUiState
|
||||
import dev.sanderling.sdk.Sanderling
|
||||
|
||||
object AuthSnapshots {
|
||||
val loggedIn by Sanderling.snapshot { Repository.session.value != null }
|
||||
val authStatus by Sanderling.snapshot { if (Repository.session.value != null) "logged-in" else "logged-out" }
|
||||
val loginError by Sanderling.snapshot { LoginUiState.loginError.value }
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package app.folio.sanderling
|
||||
|
||||
import app.folio.FocusTracker
|
||||
import app.folio.data.Repository
|
||||
import app.folio.data.TxnType
|
||||
import app.folio.feature.ledger.AddTransactionUiState
|
||||
import app.folio.navigation.Navigator
|
||||
import app.folio.navigation.Route
|
||||
import app.folio.platform.balanceOf
|
||||
import app.folio.platform.signedAmount
|
||||
import dev.sanderling.sdk.Sanderling
|
||||
|
||||
object LedgerSnapshots {
|
||||
private val activeId
|
||||
get() = when (val r = Navigator.current.value) {
|
||||
is Route.Ledger -> r.accountId
|
||||
is Route.AddTransaction -> r.accountId
|
||||
else -> null
|
||||
}
|
||||
|
||||
val activeAccountId by Sanderling.snapshot { activeId }
|
||||
val ledgerRows by Sanderling.snapshot {
|
||||
val active = activeId ?: return@snapshot emptyList<Any>()
|
||||
Repository.transactions.value.filter { it.accountId == active }.map {
|
||||
mapOf(
|
||||
"id" to it.id,
|
||||
"accountId" to it.accountId,
|
||||
"type" to if (it.type == TxnType.credit) "credit" else "debit",
|
||||
"amount" to it.amount,
|
||||
"signed" to signedAmount(it),
|
||||
)
|
||||
}
|
||||
}
|
||||
val ledgerBalance by Sanderling.snapshot {
|
||||
val active = activeId ?: return@snapshot 0L
|
||||
balanceOf(Repository.transactions.value.filter { it.accountId == active })
|
||||
}
|
||||
val focusedInput by Sanderling.snapshot { FocusTracker.current.value }
|
||||
val txnFormType by Sanderling.snapshot { AddTransactionUiState.txnFormType.value }
|
||||
val txnFormAccountId by Sanderling.snapshot { (Navigator.current.value as? Route.AddTransaction)?.accountId }
|
||||
val txnError by Sanderling.snapshot { AddTransactionUiState.txnError.value }
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package app.folio.sanderling
|
||||
|
||||
import app.folio.navigation.Navigator
|
||||
import app.folio.navigation.Route
|
||||
import dev.sanderling.sdk.Sanderling
|
||||
|
||||
object NavigationSnapshots {
|
||||
val screen by Sanderling.snapshot {
|
||||
when (Navigator.current.value) {
|
||||
Route.Login -> "login"
|
||||
Route.Home -> "home"
|
||||
Route.AddAccount -> "add-account"
|
||||
is Route.Ledger -> "ledger"
|
||||
is Route.AddTransaction -> "add-transaction"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ const loggedIn = extract<boolean>(
|
||||
(state) => (state.snapshots.logged_in as boolean) ?? false,
|
||||
);
|
||||
const route = extract<string>(
|
||||
(state) => (state.snapshots.route as string) ?? "",
|
||||
(state) => (state.snapshots.screen as string) ?? "",
|
||||
);
|
||||
const accounts = extract<AccountSnapshot[]>(
|
||||
(state) => (state.snapshots.accounts as AccountSnapshot[]) ?? [],
|
||||
|
||||
Reference in new issue
Block a user