Skip to content

Fix edit note reload on open intent#992

Merged
Crustack merged 5 commits into
mainfrom
fix/981
Apr 26, 2026
Merged

Fix edit note reload on open intent#992
Crustack merged 5 commits into
mainfrom
fix/981

Conversation

@Crustack
Copy link
Copy Markdown
Owner

@Crustack Crustack commented Apr 26, 2026

Fixes #981

Summary by CodeRabbit

  • Bug Fixes

    • Reminder/notification logic now avoids unsupported notification access on older Android versions and skips notifications for non-note items, improving reliability.
  • Refactor

    • In-place note loading and live note switching now reloads a different selected note without reinitializing the UI, and performs an async save/check before switching for smoother transitions.
    • Change history reset order adjusted for more consistent undo/redo behavior and fewer unexpected intermediate states.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dbb08ab8-08ef-401f-bb59-d1fb11640461

📥 Commits

Reviewing files that changed from the base of the PR and between e9569c9 and 9fe7451.

📒 Files selected for processing (1)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/reminders/ReminderReceiver.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/reminders/ReminderReceiver.kt

📝 Walkthrough

Walkthrough

Centralizes EditActivity note initialization into a suspend loadNote(...) and adds onNewIntent to switch base notes at runtime; guards NotificationManager.activeNotifications access behind API 23 in ReminderReceiver; ChangeHistory.reset() now clears the stack before setting stackPointer to -1.

Changes

Cohort / File(s) Summary
Note Loading / Lifecycle
app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt
Added private suspend fun loadNote(id, persistedId, savedInstanceState, initListeners) and refactored onCreate to delegate note initialization; added override fun onNewIntent(intent: Intent?) to update intent, run checkSave() async when switching base notes, and call loadNote(..., initListeners=false) to reload without reinitializing listeners/UI.
Notification Handling
app/src/main/java/com/philkes/notallyx/presentation/activity/note/reminders/ReminderReceiver.kt
Wrapped access to NotificationManager.activeNotifications with Build.VERSION.SDK_INT >= 23 guard; notify now returns early for base notes whose folder != Folder.NOTES, skipping notification creation/dispatch.
Change History
app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt
reset() now clears changeStack before setting stackPointer = -1, altering the order of internal state updates during reset.

Sequence Diagram(s)

sequenceDiagram
  participant System as "System\n(Intent)"
  participant Activity as "EditActivity"
  participant Coroutine as "lifecycleScope\n(Coroutine)"
  participant Repo as "NoteRepository / ViewModel"

  rect rgba(173,216,230,0.5)
  System->>Activity: deliver new Intent (EXTRA_SELECTED_BASE_NOTE)
  Activity->>Activity: onNewIntent(intent)\nsetIntent(intent)
  Activity->>Activity: if different base note -> launch checkSave() (suspend)
  end

  rect rgba(144,238,144,0.5)
  Activity->>Coroutine: launchWhenResumed { loadNote(selectedId, persistedId, savedState, initListeners=false) }
  Coroutine->>Repo: request note data
  Repo-->>Activity: note data / model
  Activity-->>Activity: update model state, UI, reminder chip, menus (no listener reinit)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 Hoppity-hop, I load a note with care,

Intents swap quick and coroutines spare,
Old phones are guarded, notifications neat,
I tidy stacks with a tiny heartbeat,
I nibble bugs and leave a trail of hare.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly relates to the main changes: handling intent reload when opening a note from notifications, which is the core fix for issue #981.
Linked Issues check ✅ Passed All code changes address the reported issue: onNewIntent handles intent switching for different notes, loadNote supports reload without reinitializing listeners, ReminderReceiver guards against invalid folder notifications, and ChangeHistory reset ensures proper state.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing notification navigation: EditActivity intent handling, ReminderReceiver folder validation, and ChangeHistory reset order are all necessary for resolving the multi-reminder navigation issue.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/981

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt (1)

180-185: Potential race between onCreate's load and a fast-arriving onNewIntent.

The loadNote launched here from onCreate may still be in flight (DB I/O in setState, listener wiring) when onNewIntent launches another loadNote. Both coroutines mutate notallyModel and rebuild listeners/UI without any cancellation/serialization, which can interleave state and re-attach listeners twice. Consider keeping a Job reference and cancelling the previous load before starting a new one, or guarding loadNote with a Mutex.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`
around lines 180 - 185, The onCreate launch calling loadNote can race with
onNewIntent because both start coroutines that mutate notallyModel and rewire
listeners; fix by serializing/cancelling previous loads: add a Job property
(e.g., loadNoteJob) on EditActivity and before starting a new
lifecycleScope.launch for loadNote cancelAndJoin or cancel the previous job,
then assign the new Job; alternatively wrap loadNote body with a Mutex (e.g.,
loadNoteMutex) and lock/unlock around the critical section so concurrent
invocations of loadNote (from lifecycleScope.launch in onCreate and from
onNewIntent) cannot interleave; reference loadNote, lifecycleScope.launch,
onNewIntent, and notallyModel when applying the change.
🤖 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/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 163-167: onNewIntent currently reads extras from the new Intent
but never updates the Activity.intent property, causing loadNote (which checks
intent.data, intent.action and EXTRA_DISPLAYED_LABEL) to see stale launch data;
fix by calling setIntent(intent) at the start of onNewIntent before launching
lifecycleScope so loadNote, setState and handleSharedNote operate on the
incoming Intent and not the original one.
- Around line 163-167: onNewIntent currently calls loadNote(selectedId, ...)
which ultimately calls notallyModel.setState(...) and can overwrite in-progress
edits without saving; update onNewIntent to check for unsaved changes before
loading the new note by invoking the existing checkSave()/saveNote() flow (the
same behavior used in finish() and onSaveInstanceState) and only call loadNote
when checkSave() permits or after saveNote() completes; reference the
onNewIntent, loadNote, notallyModel.setState, checkSave(), and saveNote()
symbols when making the change so the code preserves current edits before
replacing state.
- Around line 200-234: The activity currently lets getLongExtra default to 0L
which causes loadNote(id=0L, ...) -> notallyModel.setState(0L) ->
createBaseNote() and overwrites the current note; change the
onNewIntent/intent-handling code to use -1L as the missing-id sentinel for
EXTRA_SELECTED_BASE_NOTE and short-circuit when id == -1L so loadNote is not
called for invalid IDs; specifically, when reading
intent.getLongExtra(EXTRA_SELECTED_BASE_NOTE, -1L) (or intent?.getLongExtra(...,
-1L) ?: -1L) only call lifecycleScope.launch { loadNote(...) } if the selectedId
!= -1L to avoid triggering notallyModel.setState/createBaseNote for missing
extras.

---

Nitpick comments:
In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 180-185: The onCreate launch calling loadNote can race with
onNewIntent because both start coroutines that mutate notallyModel and rewire
listeners; fix by serializing/cancelling previous loads: add a Job property
(e.g., loadNoteJob) on EditActivity and before starting a new
lifecycleScope.launch for loadNote cancelAndJoin or cancel the previous job,
then assign the new Job; alternatively wrap loadNote body with a Mutex (e.g.,
loadNoteMutex) and lock/unlock around the critical section so concurrent
invocations of loadNote (from lifecycleScope.launch in onCreate and from
onNewIntent) cannot interleave; reference loadNote, lifecycleScope.launch,
onNewIntent, and notallyModel when applying the change.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 56f8affb-c09b-498c-adfe-c0d7a6e90516

📥 Commits

Reviewing files that changed from the base of the PR and between 1d999e1 and efc58c4.

📒 Files selected for processing (3)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/reminders/ReminderReceiver.kt
  • app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 207-241: loadNote(...) is being called from onCreate and
onNewIntent and re-attaches observers/listeners (setupListeners,
setupAdditionalListeners, configureUI), causing duplicate observers (e.g.,
search.results.mergeSkipFirst(...).observe(this),
search.resultPos.observeSkipFirst(this), notallyModel.viewMode.observe(this),
preferences.*.observe(this)) and duplicate text watchers
(binding.EnterSearchKeyword.doAfterTextChanged). Fix by splitting initialization
from reload: extract a one-time init method (called from onCreate) that
registers observers/listeners (move setupListeners, setupAdditionalListeners,
configureUI contents that add observers here) and make loadNote support a reload
path (called from onNewIntent) that updates state without re-registering
observers; alternatively add a boolean flag to loadNote (e.g., attachObservers:
Boolean) and guard observer/text-watcher registration so subsequent calls skip
re-attachment; also for safety, where appropriate remove existing
observers/listeners before re-attaching
(removeObserver/removeTextChangedListener) or use lifecycle-aware single-event
helpers.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ef236590-edf9-46c6-be49-1c0d98176fc5

📥 Commits

Reviewing files that changed from the base of the PR and between efc58c4 and eee350b.

📒 Files selected for processing (1)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt (1)

187-194: ⚠️ Potential issue | 🔴 Critical

Move configureUI() invocation into the loadNote coroutine, or use a post-load callback, to ensure model state is initialized first.

configureUI() and its observers run synchronously in onCreate before the loadNote coroutine executes, meaning notallyModel.setState(...) (line 211) has not yet run when subclass configureUI() methods and setupAdditionalListeners() observer registrations execute.

Confirmed risks in subclass overrides:

  • EditListActivity (line 207): calls listManager.add(pushChange = false) when notallyModel.items.isEmpty() is true, adding a blank item before the actual loaded items populate the list. After loadNote completes, setState() calls setItems() which clears and repopulates, creating a UI glitch.
  • EditNoteActivity and EditTextPlainActivity (lines 51, 83): read notallyModel.isNewNote before it's set by setState(). While the default value of true happens to work for new notes, it will be incorrect until setState() runs for existing notes being edited.
  • notallyModel.viewMode.observe(this) (line 689): fires immediately with the default NoteViewMode.EDIT value, calling toggleCanEdit() and updateToggleViewMode() against pre-load state, then re-runs once loadNote finishes and setState() updates the actual view mode.

Refactor to execute configureUI() after model initialization completes, either by moving it into loadNote() as a post-load step or by await-ing the launched coroutine before calling it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`
around lines 187 - 194, The call to configureUI() runs before loadNote(...)
completes so observers and subclass overrides (e.g., EditListActivity,
EditNoteActivity, EditTextPlainActivity) see uninitialized model state; move the
configureUI() invocation into the lifecycleScope.launch coroutine after
loadNote(...) returns (or await the coroutine before calling configureUI()), or
add a post-load callback in loadNote to invoke configureUI(); ensure
setupListeners() remains where intended and that notallyModel.setState(...)
(inside loadNote) runs before any configureUI()/setupAdditionalListeners()
observers execute.
🧹 Nitpick comments (1)
app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt (1)

163-174: LGTM — onNewIntent correctly updates the intent and saves pending edits.

The added setIntent(intent) and checkSave() calls properly address the previously raised concerns about stale intent reads and unsaved-edit loss, and guarding on selectedId != -1L avoids needlessly reloading when the activity receives an unrelated new intent.

One small nit: the sentinel here is -1L, while onCreate (line 189) uses 0L as the default for EXTRA_SELECTED_BASE_NOTE. Aligning both to the same sentinel (or extracting a small helper) would make the read paths consistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`
around lines 163 - 174, onNewIntent uses -1L as the sentinel while onCreate
reads EXTRA_SELECTED_BASE_NOTE with a default of 0L, causing inconsistent
intent-read behavior; make the sentinel consistent by choosing one value (or
create a small helper like getSelectedBaseNoteFromIntent(Intent) used by both
onNewIntent and onCreate) and update references so both onNewIntent and onCreate
use the same sentinel logic for EXTRA_SELECTED_BASE_NOTE and the same check
(e.g., selectedId != sentinel) to avoid mismatched handling of "no selection".
🤖 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/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 208-240: The title TextWatcher created by
createTextWatcherWithHistory is firing on programmatic setText in
setStateFromModel during onNewIntent reload, polluting changeHistory; to fix,
suppress watcher callbacks around the programmatic update: in setStateFromModel
(or loadNote before calling it) remove or temporarily disable the EnterTitle
TextWatcher, call binding.EnterTitle.setText(notallyModel.title), then re-attach
or re-enable the watcher so only user edits are recorded; alternatively add a
simple boolean flag (e.g., isProgrammaticEdit) checked by the watcher (in
createTextWatcherWithHistory) to ignore programmatic changes and toggle it
around setText to prevent recording the reload as an undoable change.

---

Outside diff comments:
In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 187-194: The call to configureUI() runs before loadNote(...)
completes so observers and subclass overrides (e.g., EditListActivity,
EditNoteActivity, EditTextPlainActivity) see uninitialized model state; move the
configureUI() invocation into the lifecycleScope.launch coroutine after
loadNote(...) returns (or await the coroutine before calling configureUI()), or
add a post-load callback in loadNote to invoke configureUI(); ensure
setupListeners() remains where intended and that notallyModel.setState(...)
(inside loadNote) runs before any configureUI()/setupAdditionalListeners()
observers execute.

---

Nitpick comments:
In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 163-174: onNewIntent uses -1L as the sentinel while onCreate reads
EXTRA_SELECTED_BASE_NOTE with a default of 0L, causing inconsistent intent-read
behavior; make the sentinel consistent by choosing one value (or create a small
helper like getSelectedBaseNoteFromIntent(Intent) used by both onNewIntent and
onCreate) and update references so both onNewIntent and onCreate use the same
sentinel logic for EXTRA_SELECTED_BASE_NOTE and the same check (e.g., selectedId
!= sentinel) to avoid mismatched handling of "no selection".
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 87f6744a-cce7-4b59-ae2c-35ba05dd788d

📥 Commits

Reviewing files that changed from the base of the PR and between eee350b and 81e2be1.

📒 Files selected for processing (1)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Comment thread app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`:
- Around line 206-244: The issue is that loadNote(..., initListeners = false)
skips configureUI(), so for Type.LIST the list adapters (MainListView.adapter
and CheckedListView.adapter set in configureUI()) are not rebound on onNewIntent
and old items remain; fix by splitting configureUI() into two parts (or adding a
new method) so that view-binding always runs but listener registration runs only
when needed: extract the adapter/view-binding logic into a new method (e.g.,
rebindListViews() or bindUIState()) and call it unconditionally from loadNote
(before setStateFromModel or right after), while keeping existing listener
attachment inside configureUI() guarded by a listenersInitialized flag (or only
called when initListeners is true); update subclasses (EditNoteActivity
overrides) to move adapter setup into the bind method and guard any listener
registration so repeated calls are safe.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2b57b27f-a113-4434-8aad-20b67892ef7a

📥 Commits

Reviewing files that changed from the base of the PR and between 81e2be1 and e9569c9.

📒 Files selected for processing (1)
  • app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Comment on lines +206 to +244
private suspend fun loadNote(
id: Long,
persistedId: Long?,
savedInstanceState: Bundle?,
initListeners: Boolean,
) {
changeHistory.reset()
if (persistedId == null || notallyModel.originalNote == null) {
notallyModel.setState(id, intent.data == null)
}
if (notallyModel.isNewNote) {
when (intent.action) {
Intent.ACTION_SEND,
Intent.ACTION_SEND_MULTIPLE,
Intent.ACTION_VIEW -> handleSharedNote()

else ->
intent.getStringExtra(EXTRA_DISPLAYED_LABEL)?.let {
notallyModel.setLabels(listOf(it))
}
}
}

initBottomMenu()
resetToolbars()
if (initListeners) setupListeners()
setStateFromModel(savedInstanceState)

if (
!notallyModel.isNewNote && notallyModel.type == Type.LIST && savedInstanceState == null
) {
val lastUsedViewMode = notallyModel.viewMode.value
notallyModel.viewMode.value =
preferences.defaultListNoteViewMode.value.toNoteViewMode(lastUsedViewMode)
}
if (initListeners) configureUI()
binding.ScrollView.visibility = VISIBLE
setupEditNoteReminderChip()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect concrete configureUI overrides to confirm body/list binding lives there
# and assess idempotency for re-invocation on onNewIntent.
fd -e kt | xargs rg -nP -C3 'override\s+fun\s+configureUI\s*\(\s*\)'
echo '----'
# Check how EnterBody / MainListView / CheckedListView text/adapters are populated.
rg -nP -C2 '\b(EnterBody|MainListView|CheckedListView)\b\s*\.(setText|adapter|text)\b'

Repository: Crustack/NotallyX

Length of output: 6341


🏁 Script executed:

# Extract full configureUI implementations from the two main subclasses
echo "=== EditNoteActivity.configureUI() ===" 
sed -n '48,/^    override\|^    fun\|^    private\|^}/p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt | head -80

echo ""
echo "=== EditListActivity.configureUI() ===" 
sed -n '204,/^    override\|^    fun\|^    private\|^}/p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt | head -100

Repository: Crustack/NotallyX

Length of output: 665


🏁 Script executed:

# Find setStateFromModel implementation
rg -n 'fun setStateFromModel' -A 30 app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Repository: Crustack/NotallyX

Length of output: 1375


🏁 Script executed:

# Check where updateEditText is called in EditNoteActivity
rg -n 'updateEditText' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt

Repository: Crustack/NotallyX

Length of output: 129


🏁 Script executed:

# Get context around line 112 in EditNoteActivity to see when updateEditText is called
sed -n '100,130p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt

Repository: Crustack/NotallyX

Length of output: 1152


🏁 Script executed:

# Find all invocations of updateEditText in EditNoteActivity
rg -n 'updateEditText\(\)' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt

Repository: Crustack/NotallyX

Length of output: 129


🏁 Script executed:

# Find where list adapters are bound in EditListActivity - look for adapter assignments
sed -n '240,280p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt

Repository: Crustack/NotallyX

Length of output: 1826


🏁 Script executed:

# Check if setStateFromModel has overrides in subclasses that might bind body
rg -n 'override.*setStateFromModel\|fun setStateFromModel' app/src/main/java/com/philkes/notallyx/presentation/activity/note/

Repository: Crustack/NotallyX

Length of output: 43


🏁 Script executed:

# Check if EditListActivity has any mechanism to rebind adapters after configureUI
rg -n 'binding\.(MainListView|CheckedListView)\.adapter\s*=' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt

Repository: Crustack/NotallyX

Length of output: 177


🏁 Script executed:

# Verify EditNoteActivity.setStateFromModel is actually called and does update text
sed -n '111,135p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt

Repository: Crustack/NotallyX

Length of output: 932


🏁 Script executed:

# Check the onNewIntent method to see the full flow
rg -n 'override.*onNewIntent\|fun onNewIntent' -A 5 app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Repository: Crustack/NotallyX

Length of output: 43


🏁 Script executed:

# Search for onNewIntent in all activity files
rg -n 'onNewIntent' app/src/main/java/com/philkes/notallyx/presentation/activity/note/

Repository: Crustack/NotallyX

Length of output: 315


🏁 Script executed:

# Also check the base EditActivity to understand the full architecture
rg -n 'loadNote' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt | head -20

Repository: Crustack/NotallyX

Length of output: 227


🏁 Script executed:

# Check if there's an onNewIntent that's not in the standard location
find app/src/main/java/com/philkes/notallyx/presentation/activity/note/ -name '*.kt' -exec rg -l 'onNewIntent' {} \;

Repository: Crustack/NotallyX

Length of output: 143


🏁 Script executed:

# Get the full onNewIntent implementation
sed -n '163,180p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Repository: Crustack/NotallyX

Length of output: 734


🏁 Script executed:

# Also get context around line 171 to see the full flow
sed -n '160,180p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Repository: Crustack/NotallyX

Length of output: 751


🏁 Script executed:

# Finally check if EditListActivity has any custom setStateFromModel
grep -n 'setStateFromModel\|updateEditText' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt

Repository: Crustack/NotallyX

Length of output: 187


🏁 Script executed:

# Get full EditListActivity.setStateFromModel override
sed -n '217,230p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt

Repository: Crustack/NotallyX

Length of output: 560


🏁 Script executed:

# Confirm the exact line in loadNote where configureUI is called vs where setStateFromModel is called
sed -n '206,244p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt | grep -n 'setStateFromModel\|configureUI\|initListeners'

Repository: Crustack/NotallyX

Length of output: 235


🏁 Script executed:

# Verify the order of operations in loadNote
sed -n '206,244p' app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Repository: Crustack/NotallyX

Length of output: 1405


List note content is not refreshed on onNewIntent reload — note B's items will still show note A's list.

When onNewIntent calls loadNote(..., initListeners = false), the order of operations is:

  1. setStateFromModel() is always called
  2. configureUI() is skipped (gated by initListeners)

For Type.NOTE, this works correctly: EditNoteActivity overrides setStateFromModel() to call updateEditText(), which rebinds the body text.

However, for Type.LIST, the adapter bindings (MainListView.adapter and CheckedListView.adapter, set at lines 266–271) live only inside configureUI(). Since configureUI() is skipped on onNewIntent, list adapters are never rebound, leaving the old note's items visible. This defeats the fix for #981 in the reused-activity path.

The configureUI skip was intended to avoid re-attaching listeners. The cleaner fix is to split the subclass configureUI() overrides into two parts: (a) rebind state to views (always run), and (b) register listeners (run only on first init).

🔧 One possible shape of the fix
-        if (initListeners) configureUI()
+        configureUI()

…paired with making the subclass configureUI() overrides safe to call on reload (e.g., guard listener registration with a listenersInitialized flag).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt`
around lines 206 - 244, The issue is that loadNote(..., initListeners = false)
skips configureUI(), so for Type.LIST the list adapters (MainListView.adapter
and CheckedListView.adapter set in configureUI()) are not rebound on onNewIntent
and old items remain; fix by splitting configureUI() into two parts (or adding a
new method) so that view-binding always runs but listener registration runs only
when needed: extract the adapter/view-binding logic into a new method (e.g.,
rebindListViews() or bindUIState()) and call it unconditionally from loadNote
(before setStateFromModel or right after), while keeping existing listener
attachment inside configureUI() guarded by a listenersInitialized flag (or only
called when initListeners is true); update subclasses (EditNoteActivity
overrides) to move adapter setup into the bind method and guard any listener
registration so repeated calls are safe.

@Crustack Crustack merged commit b8a8895 into main Apr 26, 2026
1 check passed
@Crustack Crustack deleted the fix/981 branch April 26, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Notification open note goes to wrong note with several reminders

1 participant