[incoming] add module for tracking incoming messages#334
Conversation
WalkthroughRegisters incoming message storage and UI: adds Room entity/DAO/repository/service/ViewModel/Fragment/Adapter, wires an Changes
Sequence DiagramsequenceDiagram
participant System as rgba(45,115,230,0.5)
participant Receiver as rgba(52,199,89,0.5)
participant Service as rgba(255,159,28,0.5)
participant Repo as rgba(153,102,255,0.5)
participant DAO as rgba(100,181,246,0.5)
participant DB as rgba(76,175,80,0.5)
participant Logs as rgba(244,67,54,0.5)
System->>Receiver: deliver InboxMessage
Receiver->>Service: save(message, sender, recipient, simNumber)
Service->>Service: buildId(message)\ncompute contentPreview & type
Service->>Repo: insert(IncomingMessage)
Repo->>DAO: insert(IncomingMessage)
DAO->>DB: INSERT incoming_messages
DB-->>DAO: OK
DAO-->>Repo: return
Repo-->>Service: return
alt persistence succeeds
Service-->>Receiver: return
else persistence throws
Service->>Logs: insert(ERROR log with message & stack trace)
Logs-->>Service: return
Service-->>Receiver: return
end
Receiver->>System: continue webhook handling
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt (1)
49-65: Consider using visual selection indicators instead of disabling buttons.Using
isEnabled = falseto indicate the active tab causes the selected button to appear grayed out, which typically communicates "unavailable" rather than "selected." Consider usingisSelected = truewith a custom selector drawable, or switching toMaterialButtonToggleGroupfor standard toggle behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt` around lines 49 - 65, The current selectOutgoing and selectIncoming use isEnabled to indicate the active tab which grays out the button; instead set visual state via isSelected (e.g., binding.buttonOutgoing.isSelected = true / isSelected = false) and remove the isEnabled toggles, and update the button backgrounds to use a selector drawable (or migrate the two buttons into a MaterialButtonToggleGroup) so selection is shown visually while keeping the fragment swaps in selectOutgoing and selectIncoming (referencing the methods selectOutgoing/selectIncoming and the views binding.buttonOutgoing and binding.buttonIncoming).app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt (1)
65-73: Minor: scroll listener could trigger unnecessary calls on empty list.When the RecyclerView is empty,
findLastVisibleItemPosition()returns-1andadapter.itemCount - 1is also-1, so the condition matches. WhileloadMore(0)safely returns early in the ViewModel, this creates unnecessary calls.Consider adding a guard:
♻️ Optional improvement
private val scrollListener = object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) + if (adapter.itemCount == 0) return val manager = recyclerView.layoutManager as? LinearLayoutManager manager?.findLastVisibleItemPosition()?.let { if (it == adapter.itemCount - 1) viewModel.loadMore(adapter.itemCount) } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt` around lines 65 - 73, The scroll listener (scrollListener -> onScrolled) can call viewModel.loadMore unnecessarily when the list is empty because findLastVisibleItemPosition() and adapter.itemCount - 1 both equal -1; update the onScrolled guard to first check that adapter.itemCount > 0 and that the found lastVisible (from manager?.findLastVisibleItemPosition()) is >= 0 before comparing it to adapter.itemCount - 1, and only call viewModel.loadMore(adapter.itemCount) when both conditions are met.INCOMING_MESSAGES_PLAN.md (1)
134-140: Tests described in plan but not implemented.The PR summary indicates "No new automated tests added for the incoming module," yet this section outlines comprehensive test coverage expectations. Consider adding at least critical-path tests (DAO unit tests for stats/pagination, receiver integration test) or creating a follow-up issue to track test debt.
Would you like me to open an issue to track the missing test coverage for the incoming module?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@INCOMING_MESSAGES_PLAN.md` around lines 134 - 140, The plan lists comprehensive tests that were not implemented; either add the critical-path tests or create a follow-up issue tracking the missing coverage. Specifically, implement unit tests for the DAO (e.g., IncomingDao.statsQuery and pagination behavior), repository tests for mapping and totals (IncomingRepository.map* / getTotals), an integration test for the receiver to assert persistence before webhook dispatch (IncomingReceiver.handleWebhook), a Fragment/ViewModel test for stats rendering and load-more (IncomingFragment / IncomingViewModel), and a migration test for old DB upgrade (MigrationUpgradeOldDb); if you won't add them now, create a tracked issue outlining these exact tests with priorities and acceptance criteria.app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt (1)
24-31: RedundantloadMore()call in init block.The
loadMore()call on line 30 is dead code. Sincelimitis initialized withchunkSize(50), the switchMap on line 25 already triggersrepository.selectLast(50)immediately. WhenloadMore()is called with defaultindex=0, the conditioncurrentLimit >= index + chunkSizeevaluates to50 >= 50, returning early without doing anything.Remove the redundant call:
♻️ Remove dead code
init { _messages.addSource(limit.switchMap { repository.selectLast(it) }) { _messages.value = it hasMore = it.size >= (limit.value ?: chunkSize) isLoading = false } - loadMore() }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt` around lines 24 - 31, The init block currently calls loadMore() redundantly because limit is initialized to chunkSize so the switchMap on limit already triggers repository.selectLast(chunkSize); remove the dead call to loadMore() from the init block (the block that sets up _messages.addSource(limit.switchMap { repository.selectLast(it) }) and the subsequent hasMore/isLoading updates) so initialization relies on the limit switchMap; leave the other logic (hasMore, isLoading updates and loadMore function) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt`:
- Around line 11-12: The synchronous DAO insert must be converted to a
coroutine-backed call: change IncomingMessagesDao.insert(message:
IncomingMessage) to a suspend fun insert(message: IncomingMessage), then update
IncomingMessagesRepository.insert, IncomingMessagesService.save and the call
site in ReceiverService.process (or the BroadcastReceiver entry points
MessagesReceiver.onReceive / MmsReceiver.onReceive) to invoke the suspend insert
from a background coroutine (e.g., launch or withContext(Dispatchers.IO)) so the
database write never runs on the main thread; ensure callers propagate suspend
or wrap repository calls in a CoroutineScope tied to a lifecycle or WorkManager
as appropriate to avoid blocking the UI thread.
In
`@app/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.kt`:
- Line 35: Replace the raw enum display (binding.textViewType.text =
item.type.name) with a localized string lookup: add string resources
incoming_type_sms, incoming_type_data_sms, incoming_type_mms and implement a
mapping from the enum (item.type) to the appropriate resource (e.g., via a when
over the enum in IncomingMessagesAdapter or an extension function on the enum)
and set binding.textViewType.text using context.getString(mappedResId) so UI
shows localized, user-friendly labels instead of internal constant names.
In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt`:
- Around line 44-46: The fragment's button state isn't restored after
configuration change; update HolderFragment to persist the selected tab and
reapply it when views are recreated: add a constant key (e.g., "SELECTED_TAB")
and save the current selection in onSaveInstanceState (store which of
selectOutgoing()/selectIncoming() is active), then in onViewCreated (or where
savedInstanceState is handled) check savedInstanceState and call
selectOutgoing() or selectIncoming() accordingly instead of skipping both when
savedInstanceState != null so the buttons' isEnabled states match the restored
child fragment.
In `@INCOMING_MESSAGES_PLAN.md`:
- Line 60: The plan and code disagree: the DAO exposes selectLast(limit) but the
plan lists selectLast(limit, offset). Update the plan to match the
implementation by replacing the signature to `selectLast(limit)` (or explicitly
document the load-more pattern used by the ViewModel that increases limit rather
than using offset-based pagination) and mention the ViewModel's load-more
behavior so readers understand why offset isn't used; reference the DAO method
name selectLast and the ViewModel load-more pattern in the plan.
- Around line 86-93: The stats card described in the plan is missing the
"webhook failed count" in the implemented UI; update the
IncomingMessagesListFragment to surface that metric by ensuring the aggregator
that computes totals (e.g., the stats selector or the method that produces
total/SMS/MMS/DataSMS counts) also calculates webhookFailedCount and pass it
into the stats card props, then render a new stat entry labeled "Webhook failed"
alongside Total, SMS, MMS and Data SMS; alternatively, if this metric is out of
scope for phase 1, update the plan text to remove "Webhook failed count" instead
of changing code.
---
Nitpick comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt`:
- Around line 24-31: The init block currently calls loadMore() redundantly
because limit is initialized to chunkSize so the switchMap on limit already
triggers repository.selectLast(chunkSize); remove the dead call to loadMore()
from the init block (the block that sets up _messages.addSource(limit.switchMap
{ repository.selectLast(it) }) and the subsequent hasMore/isLoading updates) so
initialization relies on the limit switchMap; leave the other logic (hasMore,
isLoading updates and loadMore function) unchanged.
In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt`:
- Around line 49-65: The current selectOutgoing and selectIncoming use isEnabled
to indicate the active tab which grays out the button; instead set visual state
via isSelected (e.g., binding.buttonOutgoing.isSelected = true / isSelected =
false) and remove the isEnabled toggles, and update the button backgrounds to
use a selector drawable (or migrate the two buttons into a
MaterialButtonToggleGroup) so selection is shown visually while keeping the
fragment swaps in selectOutgoing and selectIncoming (referencing the methods
selectOutgoing/selectIncoming and the views binding.buttonOutgoing and
binding.buttonIncoming).
In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt`:
- Around line 65-73: The scroll listener (scrollListener -> onScrolled) can call
viewModel.loadMore unnecessarily when the list is empty because
findLastVisibleItemPosition() and adapter.itemCount - 1 both equal -1; update
the onScrolled guard to first check that adapter.itemCount > 0 and that the
found lastVisible (from manager?.findLastVisibleItemPosition()) is >= 0 before
comparing it to adapter.itemCount - 1, and only call
viewModel.loadMore(adapter.itemCount) when both conditions are met.
In `@INCOMING_MESSAGES_PLAN.md`:
- Around line 134-140: The plan lists comprehensive tests that were not
implemented; either add the critical-path tests or create a follow-up issue
tracking the missing coverage. Specifically, implement unit tests for the DAO
(e.g., IncomingDao.statsQuery and pagination behavior), repository tests for
mapping and totals (IncomingRepository.map* / getTotals), an integration test
for the receiver to assert persistence before webhook dispatch
(IncomingReceiver.handleWebhook), a Fragment/ViewModel test for stats rendering
and load-more (IncomingFragment / IncomingViewModel), and a migration test for
old DB upgrade (MigrationUpgradeOldDb); if you won't add them now, create a
tracked issue outlining these exact tests with priorities and acceptance
criteria.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5e645013-62f9-496c-97dd-ede05556fc67
📒 Files selected for processing (19)
INCOMING_MESSAGES_PLAN.mdapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values/strings.xml
7e31f55 to
ba56f2e
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt (1)
74-77: Tab switches recreate fragments and lose RecyclerView scroll position.Using
replace(...)on lines 75 and 86 destroys and recreates the inactive tab's fragment. Since neither MessagesListFragment nor IncomingMessagesListFragment persist RecyclerView position, switching tabs resets the scroll state each time. Consider keeping both child fragments and usingshow/hideby tag instead to preserve instance state and scroll position.♻️ Proposed refactor (preserve child fragment instances)
class HolderFragment : Fragment() { + private companion object { + const val TAG_OUTGOING = "tab_outgoing" + const val TAG_INCOMING = "tab_incoming" + } + private fun selectOutgoing() { isOutgoingSelected = true - - binding.buttonOutgoing.isEnabled = false - binding.buttonIncoming.isEnabled = true - - childFragmentManager.commit { - replace(R.id.rootLayout, MessagesListFragment.newInstance()) - } + updateButtonStates() + val outgoing = childFragmentManager.findFragmentByTag(TAG_OUTGOING) + ?: MessagesListFragment.newInstance() + val incoming = childFragmentManager.findFragmentByTag(TAG_INCOMING) + + childFragmentManager.commit { + if (!outgoing.isAdded) add(R.id.rootLayout, outgoing, TAG_OUTGOING) + incoming?.let { hide(it) } + show(outgoing) + } } private fun selectIncoming() { isOutgoingSelected = false - - binding.buttonOutgoing.isEnabled = true - binding.buttonIncoming.isEnabled = false - - childFragmentManager.commit { - replace(R.id.rootLayout, IncomingMessagesListFragment.newInstance()) - } + updateButtonStates() + val incoming = childFragmentManager.findFragmentByTag(TAG_INCOMING) + ?: IncomingMessagesListFragment.newInstance() + val outgoing = childFragmentManager.findFragmentByTag(TAG_OUTGOING) + + childFragmentManager.commit { + if (!incoming.isAdded) add(R.id.rootLayout, incoming, TAG_INCOMING) + outgoing?.let { hide(it) } + show(incoming) + } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt` around lines 74 - 77, The current use of childFragmentManager.commit with replace(R.id.rootLayout, MessagesListFragment.newInstance()) (and the analogous replace for IncomingMessagesListFragment) recreates fragments and loses RecyclerView scroll state; change the logic in HolderFragment to add both child fragments once using add(..., tag) (use MessagesListFragment.newInstance() and IncomingMessagesListFragment.newInstance()), then toggle visibility with show(tag)/hide(tag) instead of replace, ensuring you reuse existing fragments by finding them via childFragmentManager.findFragmentByTag(tag) so instances (and RecyclerView position) are preserved across tab switches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt`:
- Around line 74-77: The current use of childFragmentManager.commit with
replace(R.id.rootLayout, MessagesListFragment.newInstance()) (and the analogous
replace for IncomingMessagesListFragment) recreates fragments and loses
RecyclerView scroll state; change the logic in HolderFragment to add both child
fragments once using add(..., tag) (use MessagesListFragment.newInstance() and
IncomingMessagesListFragment.newInstance()), then toggle visibility with
show(tag)/hide(tag) instead of replace, ensuring you reuse existing fragments by
finding them via childFragmentManager.findFragmentByTag(tag) so instances (and
RecyclerView position) are preserved across tab switches.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2e06bcad-b814-4135-80f0-fbdd04398232
📒 Files selected for processing (3)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (1)
- app/src/main/res/values/strings.xml
There was a problem hiding this comment.
🧹 Nitpick comments (2)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt (2)
43-65: Add a recreate/switch regression test for this flow.This fragment now has real UI state, saved-state restore, and two child-fragment paths. A focused
FragmentScenariotest that selects incoming, recreates the fragment, and asserts the restored button/child state would make this much safer to evolve.Also applies to: 72-99
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt` around lines 43 - 65, Add a FragmentScenario recreation test that exercises the saved-state/child-fragment flow: use HolderFragment via FragmentScenario, call the fragment methods (or drive UI) to selectIncoming (instead of default selectOutgoing), call scenario.recreate() to simulate process death, then assert isOutgoingSelected is false and that updateButtonStates reflects the Incoming button selected and the Incoming child fragment is attached; reference HolderFragment's onViewCreated, selectIncoming/selectOutgoing, isOutgoingSelected, KEY_OUTGOING_SELECTED and updateButtonStates to locate the state and verify the child fragment in the test.
67-69: Don’t useisEnabledas the selected-tab state.These two
Buttons inapp/src/main/res/layout/fragment_holder.xml:15-36are acting like tabs, but the active one is exposed as disabled instead of selected. That makes the current tab harder to understand for accessibility services and keyboard/DPAD users. PreferisSelected/isActivatedwith stateful styling, or a real tab/toggle component, and keep both controls enabled.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt` around lines 67 - 69, The updateButtonStates function is using isEnabled to indicate the active tab; change it to set the visual/selection state instead: keep both binding.buttonOutgoing and binding.buttonIncoming enabled (isEnabled = true) and set their isSelected (or isActivated) according to isOutgoingSelected (e.g., binding.buttonOutgoing.isSelected = isOutgoingSelected; binding.buttonIncoming.isSelected = !isOutgoingSelected). Update any click handlers to still toggle isOutgoingSelected and ensure your selector/stateful styling in fragment_holder.xml responds to the selected/activated state for proper keyboard/DPAD and accessibility behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt`:
- Around line 43-65: Add a FragmentScenario recreation test that exercises the
saved-state/child-fragment flow: use HolderFragment via FragmentScenario, call
the fragment methods (or drive UI) to selectIncoming (instead of default
selectOutgoing), call scenario.recreate() to simulate process death, then assert
isOutgoingSelected is false and that updateButtonStates reflects the Incoming
button selected and the Incoming child fragment is attached; reference
HolderFragment's onViewCreated, selectIncoming/selectOutgoing,
isOutgoingSelected, KEY_OUTGOING_SELECTED and updateButtonStates to locate the
state and verify the child fragment in the test.
- Around line 67-69: The updateButtonStates function is using isEnabled to
indicate the active tab; change it to set the visual/selection state instead:
keep both binding.buttonOutgoing and binding.buttonIncoming enabled (isEnabled =
true) and set their isSelected (or isActivated) according to isOutgoingSelected
(e.g., binding.buttonOutgoing.isSelected = isOutgoingSelected;
binding.buttonIncoming.isSelected = !isOutgoingSelected). Update any click
handlers to still toggle isOutgoingSelected and ensure your selector/stateful
styling in fragment_holder.xml responds to the selected/activated state for
proper keyboard/DPAD and accessibility behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f2aab096-0d80-43a6-96c4-509c46ac3dd4
📒 Files selected for processing (1)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt
609ce6e to
ea024cc
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt (1)
24-31: RedundantloadMore()call in init block.The
loadMore()call on line 30 is effectively a no-op. Sincelimitis initialized tochunkSize(50), whenloadMore(0)executes, the conditioncurrentLimit >= index + chunkSizeevaluates to50 >= 50, causing an early return. The initial data load is already triggered by theswitchMapwhen it observes the initiallimitvalue.Proposed fix
init { _messages.addSource(limit.switchMap { repository.selectLast(it) }) { _messages.value = it hasMore = it.size >= (limit.value ?: chunkSize) isLoading = false } - loadMore() }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt` around lines 24 - 31, The init block calls loadMore() redundantly because _messages.addSource already triggers a load for the initial limit; remove the loadMore() invocation in the init block (the call to loadMore() after the _messages.addSource(...) closure) so the initial dataset is loaded only via the limit.switchMap observer; verify behavior using the limit, chunkSize, hasMore and isLoading variables in IncomingMessagesListViewModel to ensure no other logic depends on that explicit call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt`:
- Around line 24-31: The init block calls loadMore() redundantly because
_messages.addSource already triggers a load for the initial limit; remove the
loadMore() invocation in the init block (the call to loadMore() after the
_messages.addSource(...) closure) so the initial dataset is loaded only via the
limit.switchMap observer; verify behavior using the limit, chunkSize, hasMore
and isLoading variables in IncomingMessagesListViewModel to ensure no other
logic depends on that explicit call.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d21e4c46-fa68-4473-9db4-df8d595e4d80
📒 Files selected for processing (19)
app/schemas/me.capcom.smsgateway.data.AppDatabase/19.jsonapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values/strings.xml
✅ Files skipped from review due to trivial changes (7)
- app/src/main/java/me/capcom/smsgateway/modules/incoming/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.kt
- app/schemas/me.capcom.smsgateway.data.AppDatabase/19.json
- app/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.kt
- app/src/main/res/layout/item_incoming_message.xml
- app/src/main/res/layout/fragment_incoming_messages_list.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt
🚧 Files skipped from review as they are similar to previous changes (10)
- app/src/main/java/me/capcom/smsgateway/App.kt
- app/src/main/java/me/capcom/smsgateway/data/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt
- app/src/main/java/me/capcom/smsgateway/data/AppDatabase.kt
- app/src/main/res/values/strings.xml
- app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt
- app/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.kt
- app/src/main/res/layout/fragment_holder.xml
6232f6e to
ea8a931
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt`:
- Around line 66-74: The scroll listener currently uses
findLastVisibleItemPosition() and compares it to adapter.itemCount - 1, which
calls viewModel.loadMore(0) when both are -1; update the
RecyclerView.OnScrollListener (scrollListener) in onScrolled to first capture
val lastPos = manager?.findLastVisibleItemPosition() ?: -1 and only invoke
viewModel.loadMore(adapter.itemCount) when lastPos >= 0 and adapter.itemCount >
0 and lastPos == adapter.itemCount - 1 (i.e., guard against empty lists before
calling loadMore).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b33bd09b-015c-499e-8888-685a33786814
📒 Files selected for processing (19)
app/schemas/me.capcom.smsgateway.data.AppDatabase/19.jsonapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values/strings.xml
✅ Files skipped from review due to trivial changes (8)
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/Module.kt
- app/src/main/res/layout/item_incoming_message.xml
- app/src/main/res/layout/fragment_incoming_messages_list.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.kt
- app/schemas/me.capcom.smsgateway.data.AppDatabase/19.json
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.kt
- app/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (6)
- app/src/main/java/me/capcom/smsgateway/data/Module.kt
- app/src/main/java/me/capcom/smsgateway/data/AppDatabase.kt
- app/src/main/java/me/capcom/smsgateway/App.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt
- app/src/main/res/layout/fragment_holder.xml
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt (1)
36-40: Set theLinearLayoutManagerexplicitly in code.Line 72 assumes a
LinearLayoutManager, but this fragment never sets one directly. Making it explicit avoids silent pagination breakage if the XML manager changes.Suggested change
binding.recyclerView.adapter = adapter + binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.addOnScrollListener(scrollListener) binding.recyclerView.addItemDecoration( DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt` around lines 36 - 40, The fragment attaches an adapter and a scrollListener to binding.recyclerView but never sets a LayoutManager, yet scrollListener assumes a LinearLayoutManager; explicitly set binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) (or the desired orientation) before assigning adapter/scrollListener to ensure pagination (scrollListener) works even if the XML changes; reference binding.recyclerView, scrollListener, adapter and use LinearLayoutManager in the fragment initialization block where the RecyclerView is configured.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt`:
- Around line 67-75: The onScrolled override in IncomingMessagesListFragment
triggers viewModel.loadMore(adapter.itemCount) whenever the last item is
visible, even on upward or idle scrolls; update onScrolled to first check the
scroll delta (dy > 0) before computing lastVisiblePosition so loadMore only runs
on downward scrolls. Locate the onScrolled method (override fun
onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int)), add a guard using the
dy parameter, then proceed to get the LinearLayoutManager, call
findLastVisibleItemPosition(), and invoke viewModel.loadMore(adapter.itemCount)
only when dy > 0 and the last position equals adapter.itemCount - 1.
---
Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt`:
- Around line 36-40: The fragment attaches an adapter and a scrollListener to
binding.recyclerView but never sets a LayoutManager, yet scrollListener assumes
a LinearLayoutManager; explicitly set binding.recyclerView.layoutManager =
LinearLayoutManager(requireContext()) (or the desired orientation) before
assigning adapter/scrollListener to ensure pagination (scrollListener) works
even if the XML changes; reference binding.recyclerView, scrollListener, adapter
and use LinearLayoutManager in the fragment initialization block where the
RecyclerView is configured.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6fabeba6-61a6-4695-810a-6b87976b5b14
📒 Files selected for processing (1)
app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt
8a6ae3e to
71bb894
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt (1)
14-15: Make the "latest" query deterministic.Line 14 orders only by
createdAt, so rows with the same timestamp can shuffle between emissions and make theLIMIT :limitwindow unstable. Add a unique tie-breaker.♻️ Suggested query tweak
- `@Query`("SELECT * FROM incoming_messages ORDER BY createdAt DESC LIMIT :limit") + `@Query`("SELECT * FROM incoming_messages ORDER BY createdAt DESC, id DESC LIMIT :limit")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt` around lines 14 - 15, The SELECT in function selectLast uses ORDER BY createdAt DESC which is non-deterministic when multiple rows share the same timestamp; update the query to include a unique tie-breaker (e.g., add the primary key column such as id) to the ORDER BY clause so results are stable across emissions (for example ORDER BY createdAt DESC, id DESC), ensuring selectLast(limit: Int) returns a deterministic window.app/src/main/java/me/capcom/smsgateway/data/AppDatabase.kt (1)
36-55: Add a migration test for 18 → 19.This upgrade path now runs for every existing install. A Room migration test against a real v18 schema is the safest way to catch startup-time failures from the new table/indexes before release.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/data/AppDatabase.kt` around lines 36 - 55, Add a Room migration test that verifies the AppDatabase upgrade from schema version 18 to version 19 using the same database schema and migrations configured in AppDatabase (version = 19 and AutoMigration list); write a test (e.g., AppDatabaseMigrationTest) that uses MigrationTestHelper (or SupportSQLite) to create a real v18 database (using the v18 schema SQL asset or a pre-populated file), run the migrations applied by AppDatabase (including the AutoMigration from 18 to 19), and assert the database opens and expected new tables/indexes/columns exist and queries succeed; ensure the test references AppDatabase and the migration path 18→19 so future changes fail the test if the migration is broken.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt`:
- Around line 82-94: The current catch around
incomingMessagesService.save(message, sender, recipient, simNumber) only logs
the error and allows processing to continue; change this so failures stop
further work: after calling logsService.insert(...) rethrow the exception (or
throw a new RuntimeException with the original as cause) so the caller/flow
aborts and no dispatch/webhook processing occurs when save() fails; update the
try/catch around incomingMessagesService.save in ReceiverService (the block that
calls incomingMessagesService.save and logs via logsService.insert) to rethrow
the error instead of swallowing it.
---
Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/data/AppDatabase.kt`:
- Around line 36-55: Add a Room migration test that verifies the AppDatabase
upgrade from schema version 18 to version 19 using the same database schema and
migrations configured in AppDatabase (version = 19 and AutoMigration list);
write a test (e.g., AppDatabaseMigrationTest) that uses MigrationTestHelper (or
SupportSQLite) to create a real v18 database (using the v18 schema SQL asset or
a pre-populated file), run the migrations applied by AppDatabase (including the
AutoMigration from 18 to 19), and assert the database opens and expected new
tables/indexes/columns exist and queries succeed; ensure the test references
AppDatabase and the migration path 18→19 so future changes fail the test if the
migration is broken.
In
`@app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.kt`:
- Around line 14-15: The SELECT in function selectLast uses ORDER BY createdAt
DESC which is non-deterministic when multiple rows share the same timestamp;
update the query to include a unique tie-breaker (e.g., add the primary key
column such as id) to the ORDER BY clause so results are stable across emissions
(for example ORDER BY createdAt DESC, id DESC), ensuring selectLast(limit: Int)
returns a deterministic window.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2efe7909-f979-46be-a29b-83e668e3fd8a
📒 Files selected for processing (23)
README.mdapp/schemas/me.capcom.smsgateway.data.AppDatabase/19.jsonapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-zh/strings.xmlapp/src/main/res/values/strings.xmluser-docs
✅ Files skipped from review due to trivial changes (10)
- user-docs
- README.md
- app/src/main/java/me/capcom/smsgateway/App.kt
- app/src/main/java/me/capcom/smsgateway/data/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.kt
- app/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.kt
- app/src/main/res/layout/fragment_incoming_messages_list.xml
- app/schemas/me.capcom.smsgateway.data.AppDatabase/19.json
- app/src/main/res/layout/item_incoming_message.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.kt
🚧 Files skipped from review as they are similar to previous changes (10)
- app/src/main/java/me/capcom/smsgateway/modules/incoming/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.kt
- app/src/main/res/values-zh/strings.xml
- app/src/main/res/layout/fragment_holder.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.kt
- app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt
- app/src/main/res/values-ru/strings.xml
- app/src/main/res/values/strings.xml
- app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/res/values-ru/strings.xml`:
- Around line 164-169: Restore the three missing Russian string resources by
adding entries for settings_local_address_is, settings_public_address_is, and
webhook_id_format into the values-ru/strings.xml so HomeFragment and
WebhookAdapter can find localized text instead of falling back to default
locale; locate the existing incoming/outgoing blocks in values-ru/strings.xml
and insert appropriately translated Russian values for the keys
settings_local_address_is, settings_public_address_is, and webhook_id_format
using the same resource names used in code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dccde8ae-9e96-41df-9f09-dcafa279e43d
📒 Files selected for processing (23)
README.mdapp/schemas/me.capcom.smsgateway.data.AppDatabase/19.jsonapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-zh/strings.xmlapp/src/main/res/values/strings.xmluser-docs
✅ Files skipped from review due to trivial changes (10)
- user-docs
- README.md
- app/src/main/java/me/capcom/smsgateway/data/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.kt
- app/src/main/res/layout/item_incoming_message.xml
- app/src/main/res/layout/fragment_incoming_messages_list.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.kt
- app/schemas/me.capcom.smsgateway.data.AppDatabase/19.json
🚧 Files skipped from review as they are similar to previous changes (7)
- app/src/main/java/me/capcom/smsgateway/App.kt
- app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.kt
- app/src/main/res/values-zh/strings.xml
- app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt
- app/src/main/res/values/strings.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt
91167ef to
5561e4e
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt (1)
72-85: Consider avoidingshow()/hide()for tab switching with these list fragments.
show()/hide()keeps the hidden fragment's view lifecycle active. BothMessagesListFragment.ktandIncomingMessagesListFragment.ktattachLiveDataobservers andRecyclerViewscroll listeners inonViewCreated(), so the inactive tab continues receiving list updates and scroll events while off-screen. If that extra work isn't intentional, usereplace()or gate the observers/pagination viaonHiddenChanged()instead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt` around lines 72 - 85, selectOutgoing currently uses childFragmentManager.commit with show()/hide(), which keeps the hidden fragment's view lifecycle active and lets MessagesListFragment and IncomingMessagesListFragment continue receiving LiveData updates and scroll events; change the fragment transaction to use replace(...) for TAG_OUTGOING (remove show/hide and add/replace the outgoing fragment) so only the active fragment has its view lifecycle, or alternatively modify MessagesListFragment and IncomingMessagesListFragment to gate observer/scroll listener attachment in onHiddenChanged()/setMenuVisibility()/onResume() so observers are only active when visible (update selectOutgoing to stop calling hide/show and update childFragmentManager.commit accordingly).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/ui/HolderFragment.kt`:
- Around line 72-85: selectOutgoing currently uses childFragmentManager.commit
with show()/hide(), which keeps the hidden fragment's view lifecycle active and
lets MessagesListFragment and IncomingMessagesListFragment continue receiving
LiveData updates and scroll events; change the fragment transaction to use
replace(...) for TAG_OUTGOING (remove show/hide and add/replace the outgoing
fragment) so only the active fragment has its view lifecycle, or alternatively
modify MessagesListFragment and IncomingMessagesListFragment to gate
observer/scroll listener attachment in
onHiddenChanged()/setMenuVisibility()/onResume() so observers are only active
when visible (update selectOutgoing to stop calling hide/show and update
childFragmentManager.commit accordingly).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1566948d-1614-41fe-8c7a-c247ab6c5cdd
📒 Files selected for processing (23)
README.mdapp/schemas/me.capcom.smsgateway.data.AppDatabase/19.jsonapp/src/main/java/me/capcom/smsgateway/App.ktapp/src/main/java/me/capcom/smsgateway/data/AppDatabase.ktapp/src/main/java/me/capcom/smsgateway/data/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/Module.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessagesDao.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.ktapp/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.ktapp/src/main/java/me/capcom/smsgateway/ui/HolderFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.ktapp/src/main/java/me/capcom/smsgateway/ui/adapters/IncomingMessagesAdapter.ktapp/src/main/res/layout/fragment_holder.xmlapp/src/main/res/layout/fragment_incoming_messages_list.xmlapp/src/main/res/layout/item_incoming_message.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-zh/strings.xmlapp/src/main/res/values/strings.xmluser-docs
✅ Files skipped from review due to trivial changes (10)
- user-docs
- README.md
- app/src/main/java/me/capcom/smsgateway/modules/incoming/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/repositories/IncomingMessagesRepository.kt
- app/src/main/res/layout/item_incoming_message.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessageTotals.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/IncomingMessagesService.kt
- app/src/main/res/layout/fragment_incoming_messages_list.xml
- app/src/main/res/layout/fragment_holder.xml
- app/src/main/java/me/capcom/smsgateway/modules/incoming/db/IncomingMessage.kt
🚧 Files skipped from review as they are similar to previous changes (7)
- app/src/main/java/me/capcom/smsgateway/App.kt
- app/src/main/java/me/capcom/smsgateway/data/Module.kt
- app/src/main/java/me/capcom/smsgateway/modules/incoming/vm/IncomingMessagesListViewModel.kt
- app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt
- app/src/main/java/me/capcom/smsgateway/ui/IncomingMessagesListFragment.kt
- app/src/main/res/values/strings.xml
- app/src/main/res/values-ru/strings.xml
🤖 Pull request artifacts
|
Motivation
Description
modules/incomingfeature withIncomingMessageentity,IncomingMessagesDao,IncomingMessagesRepository,IncomingMessagesService, andIncomingMessagesListViewModelto persist and expose incoming records and aggregated totals.IncomingMessagesListFragment,IncomingMessagesAdapter, layout resources (fragment_incoming_messages_list.xml,item_incoming_message.xml), and updatesHolderFragmentandfragment_holder.xmlto allow switching between outgoing and incoming lists via two buttons.incomingModuletoApp.ktand registeringincomingMessagesDaoinAppDatabaseanddatamodule, and bumps Room DBversionto19with anAutoMigrationentry.IncomingMessagesServiceintoReceiverServiceand callingincomingMessagesService.save(...)when messages are processed, plus simple preview/id generation logic for incoming items.Testing
./gradlew assembleDebugto verify compilation and resource linking, which completed successfully../gradlew testto ensure no regressions in current tests, and they passed.Codex Task
Summary by CodeRabbit
New Features
Bug Fixes
Chores
Documentation