Skip to content

Commit fc73fb2

Browse files
authored
fix(activity): show Convert transactions in the feed (#1281)
* fix(activity): show Convert transactions in the feed A swap spans two mints, so the backend leaves `payment_amount` unset and carries both amounts in `additional_metadata` instead. `ActivityFeedMessageMapper` only ever read `payment_amount`, so every Convert cached with a null amount, rate, and mint — which meant it matched no token's activity query and rendered blank in the global feed. - Map multi-mint amounts from `additional_metadata` when `payment_amount` is absent. - Attribute a Convert to *both* mints, so it appears on the source and destination token screens (`MintInvolvement` + the metadata clause in `observeRecentForMint`). - Render it the way iOS does: overlapping dual-token avatar, from-amount on top, `-<fee> Fee` beneath. - Title the row with the two token names ("Moony -> Jeffy") rather than the server's bare "Converted", falling back to the server text until both tokens resolve. Rows cached before this can't be repaired in place (the amounts were never persisted) and can't be re-fetched either, since sync only walks forward from the newest cached id. DB 28 -> 29 clears `messages` so the next sync re-seeds from scratch — the same approach as the existing 1->2, 6->7, 7->8 and 9->10 migrations. Also fixes a silent data-loss path found alongside it: `MessageDataSource.upsert` no-oped when the per-user DB wasn't open yet, discarding a whole fetched page while the coordinator still reported `Synced`. Because every sync path pages forward from the newest cached id, those notifications were never requested again. It now fails loudly (matching `observe()`, which already errors on a missing DB), the mediator turns that into a retryable error, and the coordinator only reports `Synced` once the write has actually landed. * test(persistence): cover the v29 feed-clearing migration Folds in the standalone migration work from #1284, which duplicated the 28 -> 29 clear this branch already carries. Adds TransactionHistoryMigrationTest, following the hand-rolled pattern in UserProfileMigrationTest: asserts the feed is emptied, that a neighbouring table survives, and that it's a no-op on an already-empty feed. Also switches Migration28To29 to the onPostMigrate(SQLiteConnection) overload. Room's SupportSQLiteDatabase variant only fires when the database is built without a driver, so a future setDriver would turn the delete into a silent no-op.
1 parent f0e8380 commit fc73fb2

19 files changed

Lines changed: 1453 additions & 22 deletions

File tree

‎apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/feed/ActivityFeedMessage.kt‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ import kotlinx.serialization.Serializable
99
import kotlinx.serialization.json.Json
1010
import kotlin.time.Instant
1111

12+
/**
13+
* A feed entry paired with the token metadata its row needs.
14+
*
15+
* [token] is the entry's own token (for a convert, the source side). [toToken] is only set for a
16+
* convert, which spans two mints and draws both logos; everything else leaves it null.
17+
*/
1218
data class ActivityFeedMessageWithToken(
1319
val message: ActivityFeedMessage,
14-
val token: Token?
20+
val token: Token?,
21+
val toToken: Token? = null,
1522
)
1623

1724
data class ActivityFeedMessage(

‎apps/flipcash/features/balance/src/test/kotlin/com/flipcash/app/balance/internal/WalletLoadingStateTest.kt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class WalletLoadingStateTest {
2828
avatar = TransactionAvatar.Generic,
2929
signedAmountPrefix = "+",
3030
amount = null,
31+
fee = null,
3132
canCancel = false,
3233
)
3334

0 commit comments

Comments
 (0)