feat: chat profile screen, block/unblock & blocklist - #1174
Merged
Conversation
…kages Move MyAccount and UserProfile screen/viewmodel files into internal/myaccount and internal/userprofile subpackages and update imports/tests accordingly.
Add a blocked_users table (BlockedUserEntity + BlockedUserDao, incl. an atomic replaceAll) storing each blocked user's id, blocked-at time, and a minimal resolved display profile so the list renders offline. Bump FlipcashDatabase to v25 via an additive AutoMigration.
Add BlockedUserDataSource and BlocklistRemoteMediator: page the server blocklist (opaque cursor, atomic replaceAll on refresh), resolve each user's display profile via ProfileController, and cache into Room as the single source of truth. One-way Mapper<> impls convert between server model, entity, and the new core BlockedUserProfile.
Filter ChatMetadata.isHidden out of FeedOperations.feed so hidden DMs (e.g. a blocked chat) drop out of the Tips/Contact feeds, and add ChatCoordinator.setChatHidden (DAO updateHidden -> datasource setHidden) so blocking/unblocking can flip it optimistically — the feed, which observes Room, updates live without a server round-trip.
Add ListItem and MenuList overloads that let the caller drive the trailing endSlot (chevron, loading spinner, etc.) instead of a fixed chevron, so a row can show per-item state. Existing overloads are unchanged.
New :apps:flipcash:shared:blocklist module with an auth-gated (deduped) Pager coordinator that owns block/unblock (both toggle the chat's hidden flag) and a one-shot refresh(). RealSessionController.onAppInForeground now calls blocklistCoordinator.refresh() so the local blocklist stays current on launch/resume without opening the screen.
Blocked-users list: an 'Blocked' app bar over a paged LazyColumn of blocked users (blurred BlurHash avatar + name), tap-to-unblock with a confirmation and a per-row spinner (LoadingSuccessState), a debounced 'No One Blocked' empty state, and a blurred mode added to ContactAvatar.
Vendor the profile.v1 UserProfile.join_ts field and thread it through the domain UserProfile as joinedAt: Instant?, mapped in UserProfileMapper.
Add the tip-DM chat profile screen (blurred-avatar header, name, joined date, and a Block action that routes through BlocklistCoordinator and returns to the Tips list on success). Moves ChatParticipant to :core, adds the ChatStep.Profile step + AppRoute.Menu.Blocklist wiring, the blocklist nav entry, and supporting chat/media model and component updates.
RealSessionController gained a blocklistCoordinator constructor param (launch/ resume blocklist refresh); update the two tests that build it directly so the session unit-test sources compile.
Drop 9 unused imports left across the chat-profile and blocklist changes (ChatAmountEntryScreen, ChatActionHandler, Spacer/fillMaxWidth, BlocklistController, Box/Spacer/Scannable, DepositDelegate).
These slipped into the chat-profile/blocklist branch and are being PR'd on their own: - TipCardScreen: share-button/tip-card layout (reverted to code/cash) - ChatBottomBar: dismiss keyboard on the $ send button (removed the wrap) - ChatFlowScreen: dismiss keyboard before navigating away (removed the wrap) - ContactInfoContainer: restore the Indicator spacer + null preview Pre-existing keyboard.hideIfVisible wraps and the ViewProfile wrap are kept.
bmc08gt
force-pushed
the
feat/chat-profile
branch
from
July 31, 2026 01:01
1637b56 to
2563c87
Compare
Add a Blocklist beta feature flag. The My Account blocklist entry only shows when the flag is enabled, and opening a chat participant's profile (the entry point to blocking) is gated the same way: ChatViewModel observes the flag and exposes canViewProfile in its state, so the top-bar tap and contact-card chevron are suppressed when the flag is off.
Show an error alert when blocking a user from their chat profile or unblocking from the blocklist fails, so failures aren't silent. Also switch the unblock confirmation prompt to showMessage.
bmc08gt
force-pushed
the
feat/chat-profile
branch
from
July 31, 2026 01:05
2563c87 to
b64d8b4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the tip-DM chat profile screen and a full blocklist feature (block / unblock with an offline-first blocked-users list), plus the supporting data-layer and UI plumbing.
Chat profile
Joined {Month Year}line, and a Block action.profile.v1 UserProfile.join_tsand threads it through the domainUserProfile.joinedAt.BlocklistCoordinatorand, on success, exits the chat flow back to the Tips list.Blocklist
blocked_userstable (db v25, additive AutoMigration) →BlocklistRemoteMediator(paged, opaque server cursor, atomicreplaceAllon refresh) →BlocklistCoordinator(auth-gated, deduped Pager) →BlocklistScreen.isHiddenflag, andFeedOperations.feednow filtersisHidden, so a blocked DM drops out of (and an unblocked one returns to) the Tips feed live — no server round-trip.RealSessionController.onAppInForegroundrefreshes the blocklist so it stays current without opening the screen.LazyColumnwith blurred BlurHash avatars, tap-to-unblock (confirmation + per-row spinner viaLoadingSuccessState), and a debounced "No One Blocked" empty state (rides out the RemoteMediator → PagingSource hand-off so it never flashes).MenuList/ListItem: a newendSlotoverload lets the chat-profile "Block" row swap its chevron for a loading spinner.Commits (layered)
refactor(myaccount)— reorganize account/profile screens into subpackagesfeat(blocklist)— cache blocked users in Room (db v25)feat(blocklist)— paged RemoteMediator + offline data sourcefeat(chat)— hide chats from the feed, toggleable locallyfeat(ui)— slot-driven end content for MenuList/ListItemfeat(blocklist)— BlocklistCoordinator module + launch/resume syncfeat(blocklist)— blocked-users screenfeat(profile)— expose user join date (join_ts)feat(messenger)— chat profile screen with block/unblock and join dateTesting
./gradlew :apps:flipcash:app:assembleDebug— green.