{
	"issue": {
		"url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
		"repository_url": "https://api.github.com/repos/laurent22/joplin",
		"labels_url": "https://api.github.com/repos/laurent22/joplin/issues/14651/labels{/name}",
		"comments_url": "https://api.github.com/repos/laurent22/joplin/issues/14651/comments",
		"events_url": "https://api.github.com/repos/laurent22/joplin/issues/14651/events",
		"html_url": "https://github.com/laurent22/joplin/pull/14651",
		"id": 4042718997,
		"node_id": "PR_kwDOBLftOs7I7Sv0",
		"number": 14651,
		"title": "Desktop: Resolves #14621: Application crashes when deleting a notebook ",
		"user": {
			"login": "Pixels57",
			"id": 111073325,
			"node_id": "U_kgDOBp7YLQ",
			"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
			"gravatar_id": "",
			"url": "https://api.github.com/users/Pixels57",
			"html_url": "https://github.com/Pixels57",
			"followers_url": "https://api.github.com/users/Pixels57/followers",
			"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
			"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
			"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
			"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
			"organizations_url": "https://api.github.com/users/Pixels57/orgs",
			"repos_url": "https://api.github.com/users/Pixels57/repos",
			"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
			"received_events_url": "https://api.github.com/users/Pixels57/received_events",
			"type": "User",
			"user_view_type": "public",
			"site_admin": false
		},
		"labels": [
			{
				"id": 519700741,
				"node_id": "MDU6TGFiZWw1MTk3MDA3NDE=",
				"url": "https://api.github.com/repos/laurent22/joplin/labels/bug",
				"name": "bug",
				"color": "cf353b",
				"default": true,
				"description": "It's a bug"
			},
			{
				"id": 1080341216,
				"node_id": "MDU6TGFiZWwxMDgwMzQxMjE2",
				"url": "https://api.github.com/repos/laurent22/joplin/labels/desktop",
				"name": "desktop",
				"color": "ffc274",
				"default": false,
				"description": "All desktop platforms"
			}
		],
		"state": "closed",
		"locked": false,
		"assignees": [],
		"milestone": null,
		"comments": 9,
		"created_at": "2026-03-09T00:59:04Z",
		"updated_at": "2026-03-16T21:56:45Z",
		"closed_at": "2026-03-16T20:49:41Z",
		"assignee": null,
		"author_association": "CONTRIBUTOR",
		"active_lock_reason": null,
		"draft": false,
		"pull_request": {
			"url": "https://api.github.com/repos/laurent22/joplin/pulls/14651",
			"html_url": "https://github.com/laurent22/joplin/pull/14651",
			"diff_url": "https://github.com/laurent22/joplin/pull/14651.diff",
			"patch_url": "https://github.com/laurent22/joplin/pull/14651.patch",
			"merged_at": "2026-03-16T20:49:41Z"
		},
		"body": "<!--\r\n\r\nBefore contributing, please read the contribution guidelines: https://github.com/laurent22/joplin/blob/dev/readme/dev/index.md\r\n\r\nIf this is a Google Summer of Code pull request, please read the [GSoC pull request guidelines](https://github.com/joplin/gsoc/blob/master/pull_request_guidelines.md).\r\n\r\n---\r\n\r\n**Pull request title**: Please prefix the title with the platform you are targetting.\r\n\r\nHere are some examples of good titles:\r\n\r\n- Desktop: Resolves #123: Added new setting to change font\r\n- Mobile, Desktop: Fixes #456: Fixed config screen error\r\n- All: Resolves #777: Made synchronisation faster\r\n\r\nAnd here's an explanation of the title format:\r\n\r\n- \"Desktop\" for the Windows/macOS/Linux app (Electron app)\r\n- \"Mobile\" for the mobile app (or \"Android\" / \"iOS\" if the pull request only applies to one of the mobile platforms)\r\n- \"CLI\" for the CLI app\r\n\r\nIf it's two platforms, separate them with commas - \"Desktop, Mobile\" or if it's for all platforms, prefix with \"All\".\r\n\r\nIf it's not related to any platform (such as a translation, change to the documentation, etc.), simply don't add a platform.\r\n\r\nThen please append the issue that you've addressed or fixed. Use \"Resolves #123\" for new features or improvements and \"Fixes #123\" for bug fixes.\r\n\r\n-->\r\n\r\n## Problem\r\nWhen deleting a notebook that contains a large number of notes (Approx 600+), the app crashes with **\"Maximum update depth exceeded\"**. The error occurs due to bulk removal of note list items.\r\n## Solution\r\nThe crash was caused by the note list item hook storing the created DOM element in React state and updating it inside `useEffect`. When many items were removed in one go, each item’s effect ran in the same commit and called `setState`, which causeddmore updates and led to nested updates beyond React’s limit.\r\n\r\n**The fix** is to stop storing the item element in state. The hook now keeps the created DOM node in a **ref** instead. Updating a ref does not cause a re-render, so when many items run their effect during a bulk delete, there are no nested state updates and the crash is avoided.\r\n\r\nChanges:\r\n- useItemElement: Use a ref instead of state for the item DOM element so the effect doesn’t trigger re-renders, and return the ref.\r\n- useItemEventHandlers: Accept an element or a ref; in the effect, read the element from the ref when needed and attach/remove listeners as before.\r\n\r\n## Test Plan\r\n- **Unit tests:** Added tests in `useItemElement.test.ts` and `useItemEventHandlers.test.ts` (6 tests) that cover: hook returns a ref; element is assigned to ref and cleaned up; null rootElement; ref accepted by event handlers; null ref handling; listener cleanup.\r\n- **Run unit tests:** From repo root, `cd packages/app-desktop` then run:\r\n  - `yarn test --testPathPattern=\"NoteListItem/utils/useItemElement|NoteListItem/utils/useItemEventHandlers\"`  \r\n  or, if the script is present, `yarn test:note-list-item`.\r\n- **Manual check:** Delete a notebook that contains many notes (e.g. 100+); the app should not crash and the list and selection should update correctly.\r\n\r\n## AI Disclosure\r\n- Used AI to help me navigate through codebase\r\n- Used AI to refactor the code and optimize\r\n\r\n\r\nFixes #14621",
		"closed_by": {
			"login": "laurent22",
			"id": 1285584,
			"node_id": "MDQ6VXNlcjEyODU1ODQ=",
			"avatar_url": "https://avatars.githubusercontent.com/u/1285584?v=4",
			"gravatar_id": "",
			"url": "https://api.github.com/users/laurent22",
			"html_url": "https://github.com/laurent22",
			"followers_url": "https://api.github.com/users/laurent22/followers",
			"following_url": "https://api.github.com/users/laurent22/following{/other_user}",
			"gists_url": "https://api.github.com/users/laurent22/gists{/gist_id}",
			"starred_url": "https://api.github.com/users/laurent22/starred{/owner}{/repo}",
			"subscriptions_url": "https://api.github.com/users/laurent22/subscriptions",
			"organizations_url": "https://api.github.com/users/laurent22/orgs",
			"repos_url": "https://api.github.com/users/laurent22/repos",
			"events_url": "https://api.github.com/users/laurent22/events{/privacy}",
			"received_events_url": "https://api.github.com/users/laurent22/received_events",
			"type": "User",
			"user_view_type": "public",
			"site_admin": false
		},
		"reactions": {
			"url": "https://api.github.com/repos/laurent22/joplin/issues/14651/reactions",
			"total_count": 0,
			"+1": 0,
			"-1": 0,
			"laugh": 0,
			"hooray": 0,
			"confused": 0,
			"heart": 0,
			"rocket": 0,
			"eyes": 0
		},
		"timeline_url": "https://api.github.com/repos/laurent22/joplin/issues/14651/timeline",
		"performed_via_github_app": null,
		"state_reason": null
	},
	"comments": [
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020461516",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4020461516",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4020461516,
			"node_id": "IC_kwDOBLftOs7vo1_M",
			"user": {
				"login": "github-actions[bot]",
				"id": 41898282,
				"node_id": "MDM6Qm90NDE4OTgyODI=",
				"avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/github-actions%5Bbot%5D",
				"html_url": "https://github.com/apps/github-actions",
				"followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers",
				"following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}",
				"gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions",
				"organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs",
				"repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos",
				"events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}",
				"received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events",
				"type": "Bot",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-09T00:59:15Z",
			"updated_at": "2026-03-16T21:56:46Z",
			"body": "****CLA Assistant Lite bot**** All contributors have signed the CLA  ✍️ ✅",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020461516/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": {
				"id": 15368,
				"client_id": "Iv1.05c79e9ad1f6bdfa",
				"slug": "github-actions",
				"node_id": "MDM6QXBwMTUzNjg=",
				"owner": {
					"login": "github",
					"id": 9919,
					"node_id": "MDEyOk9yZ2FuaXphdGlvbjk5MTk=",
					"avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4",
					"gravatar_id": "",
					"url": "https://api.github.com/users/github",
					"html_url": "https://github.com/github",
					"followers_url": "https://api.github.com/users/github/followers",
					"following_url": "https://api.github.com/users/github/following{/other_user}",
					"gists_url": "https://api.github.com/users/github/gists{/gist_id}",
					"starred_url": "https://api.github.com/users/github/starred{/owner}{/repo}",
					"subscriptions_url": "https://api.github.com/users/github/subscriptions",
					"organizations_url": "https://api.github.com/users/github/orgs",
					"repos_url": "https://api.github.com/users/github/repos",
					"events_url": "https://api.github.com/users/github/events{/privacy}",
					"received_events_url": "https://api.github.com/users/github/received_events",
					"type": "Organization",
					"user_view_type": "public",
					"site_admin": false
				},
				"name": "GitHub Actions",
				"description": "Automate your workflow from idea to production",
				"external_url": "https://help.github.com/en/actions",
				"html_url": "https://github.com/apps/github-actions",
				"created_at": "2018-07-30T09:30:17Z",
				"updated_at": "2026-05-05T14:51:38Z",
				"permissions": {
					"actions": "write",
					"administration": "read",
					"artifact_metadata": "write",
					"attestations": "write",
					"checks": "write",
					"code_quality": "write",
					"contents": "write",
					"copilot_requests": "write",
					"deployments": "write",
					"discussions": "write",
					"issues": "write",
					"merge_queues": "write",
					"metadata": "read",
					"models": "read",
					"packages": "write",
					"pages": "write",
					"pull_requests": "write",
					"repository_hooks": "write",
					"repository_projects": "write",
					"security_events": "write",
					"statuses": "write",
					"vulnerability_alerts": "read"
				},
				"events": [
					"branch_protection_rule",
					"check_run",
					"check_suite",
					"create",
					"delete",
					"deployment",
					"deployment_status",
					"discussion",
					"discussion_comment",
					"fork",
					"gollum",
					"issues",
					"issue_comment",
					"label",
					"merge_group",
					"milestone",
					"page_build",
					"public",
					"pull_request",
					"pull_request_review",
					"pull_request_review_comment",
					"push",
					"registry_package",
					"release",
					"repository",
					"repository_dispatch",
					"status",
					"watch",
					"workflow_dispatch",
					"workflow_run"
				]
			}
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020462232",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4020462232",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4020462232,
			"node_id": "IC_kwDOBLftOs7vo2KY",
			"user": {
				"login": "coderabbitai[bot]",
				"id": 136622811,
				"node_id": "BOT_kgDOCCSy2w",
				"avatar_url": "https://avatars.githubusercontent.com/in/347564?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/coderabbitai%5Bbot%5D",
				"html_url": "https://github.com/apps/coderabbitai",
				"followers_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/followers",
				"following_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/following{/other_user}",
				"gists_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/subscriptions",
				"organizations_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/orgs",
				"repos_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/repos",
				"events_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/events{/privacy}",
				"received_events_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/received_events",
				"type": "Bot",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-09T00:59:38Z",
			"updated_at": "2026-03-16T00:17:21Z",
			"body": "<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: review paused by coderabbit.ai -->\n\n> [!NOTE]\n> ## Reviews paused\n> \n> It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the `reviews.auto_review.auto_pause_after_reviewed_commits` setting.\n> \n> Use the following commands to manage reviews:\n> - `@coderabbitai resume` to resume automatic reviews.\n> - `@coderabbitai review` to trigger a single review.\n> \n> Use the checkboxes below for quick actions:\n> - [ ] <!-- {\"checkboxId\": \"7f6cc2e2-2e4e-497a-8c31-c9e4573e93d1\"} --> ▶️ Resume reviews\n> - [ ] <!-- {\"checkboxId\": \"e9bb8d72-00e8-4f67-9cb2-caf3b22574fe\"} --> 🔍 Trigger review\n\n<!-- end of auto-generated comment: review paused by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nRefactored `useItemElement` hook to replace state-based element management with ref-based approach, consolidating event listener attachment into a single effect to resolve React 19 compatibility issues. Moved event handler logic from standalone hook into hook parameters, deleted `useItemEventHandlers`, and added comprehensive test coverage.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**useItemElement Hook Refactor** <br> `packages/app-desktop/gui/NoteListItem/utils/useItemElement.ts`, `packages/app-desktop/gui/NoteListItem/utils/useItemElement.test.ts`|Replaced `useState` with `useRef` for element storage, changed return type from `HTMLDivElement` to `React.MutableRefObject<HTMLDivElement \\| null>`, and made `rootElement` parameter nullable. Introduced `addItemEventListeners` helper to attach DOM event listeners. Consolidated focus-visible handling and cleanup logic into single effect. Added unit tests covering ref creation, element lifecycle, and null root handling.|\n|**Event Handler Refactoring** <br> `packages/app-desktop/gui/NoteListItem/utils/useItemEventHandlers.ts`, `packages/app-desktop/gui/NoteListItem/NoteListItem.tsx`|Removed entire `useItemEventHandlers` hook implementation and replaced with `itemEventHandlers` object passed to `useItemElement`. Updated imports to use new `ItemEventHandlers` type instead of hook utility.|\n|**Type Definitions** <br> `packages/app-desktop/gui/NoteListItem/utils/types.ts`|Added new `ItemEventHandlers` type with `onInputChange` and `onClick \\| null` properties.|\n|**Ignore File Updates** <br> `.eslintignore`, `.gitignore`|Added test file entries and removed previous utility file from ignore lists.|\n\n</details>\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 6</summary>\n\n<details>\n<summary>✅ Passed checks (6 passed)</summary>\n\n|               Check name              | Status   | Explanation                                                                                                                                                                                                                                                      |\n| :-----------------------------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|              Title check              | ✅ Passed | The pull request title clearly and accurately summarizes the main change: fixing an application crash when deleting a notebook by refactoring the useItemElement hook.                                                                                           |\n|           Description check           | ✅ Passed | The description is comprehensive and directly related to the changeset, explaining the problem, solution, changes made, and test plan for fixing the React 19 update depth issue.                                                                                |\n|          Linked Issues check          | ✅ Passed | The pull request successfully addresses all key objectives from issue `#14621`: eliminating state updates in effects by using refs, ensuring proper event listener attachment/removal, handling nullable elements, and adding unit tests for the refactored hooks. |\n|       Out of Scope Changes check      | ✅ Passed | All code changes are directly scoped to the objectives of issue `#14621`. The PR modifies useItemElement, removes useItemEventHandlers, updates NoteListItem and types, and adds tests—all necessary for the crash fix.                                            |\n|           Docstring Coverage          | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.                                                                                                                                                       |\n| Pr Description Must Follow Guidelines | ✅ Passed | The pull request description fully adheres to guidelines with properly formatted title, clear problem description, solution explanation, comprehensive test plans, and appropriate disclosures meeting all GSoC requirements.                                    |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- pr_review_plan_action_start -->\n\n<details>\n<summary>📝 Coding Plan</summary>\n\n- [ ] <!-- {\"checkboxId\": \"6ad8a4e1-0b3a-4ea2-9b5b-d82c1f47d1f2\"} --> Generate coding plan for human review comments\n\n</details>\n\n<!-- pr_review_plan_action_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=laurent22/joplin&utm_content=14651)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- [encoded data, 15396 characters] -->\n\n<!-- internal state end -->\n<!-- usage_tips_start -->\n\n> [!TIP]\n> <details>\n> <summary>You can customize the high-level summary generated by CodeRabbit.</summary>\n> \n> Configure the `reviews.high_level_summary_instructions` setting to provide custom instructions for generating the high-level summary.\n> \n> </details>\n\n<!-- usage_tips_end -->",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020462232/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": {
				"id": 347564,
				"client_id": "Iv1.6aaafe4fe882736b",
				"slug": "coderabbitai",
				"node_id": "A_kwHOB96YWc4ABU2s",
				"owner": {
					"login": "coderabbitai",
					"id": 132028505,
					"node_id": "O_kgDOB96YWQ",
					"avatar_url": "https://avatars.githubusercontent.com/u/132028505?v=4",
					"gravatar_id": "",
					"url": "https://api.github.com/users/coderabbitai",
					"html_url": "https://github.com/coderabbitai",
					"followers_url": "https://api.github.com/users/coderabbitai/followers",
					"following_url": "https://api.github.com/users/coderabbitai/following{/other_user}",
					"gists_url": "https://api.github.com/users/coderabbitai/gists{/gist_id}",
					"starred_url": "https://api.github.com/users/coderabbitai/starred{/owner}{/repo}",
					"subscriptions_url": "https://api.github.com/users/coderabbitai/subscriptions",
					"organizations_url": "https://api.github.com/users/coderabbitai/orgs",
					"repos_url": "https://api.github.com/users/coderabbitai/repos",
					"events_url": "https://api.github.com/users/coderabbitai/events{/privacy}",
					"received_events_url": "https://api.github.com/users/coderabbitai/received_events",
					"type": "Organization",
					"user_view_type": "public",
					"site_admin": false
				},
				"name": "coderabbitai",
				"description": "# Transforming Code Reviews with AI\r\n\r\n## Features\r\n\r\n**Automated Reviews**: Continuous reviews of the pull requests including incremental commits. \r\n\r\n**Summarization**: Generates high-level summary and a technical walkthrough of the PR changes. \r\n\r\n**Line-by-line review**: Provides line-by-line suggestions committable with one click.\r\n\r\n**Codebase verification**:  Verifies the impact on the overall codebase and identifies missing changes.\r\n\r\n**Insights into your code**:  Ask any questions on your codebase within the pull request \r\n\r\n**Chat about your code** : Chat with the bot around your code. The more you chat, the smarter it gets.\r\n\r\n**Issue Validation**:  Validates the PR against the linked issues and identifies other related issues \r\n\r\n\r\n\r\n",
				"external_url": "https://coderabbit.ai?utm_source=cr_app&utm_medium=github",
				"html_url": "https://github.com/apps/coderabbitai",
				"created_at": "2023-06-14T15:47:27Z",
				"updated_at": "2026-03-14T07:58:44Z",
				"permissions": {
					"actions": "read",
					"checks": "write",
					"contents": "write",
					"discussions": "read",
					"issues": "write",
					"members": "read",
					"metadata": "read",
					"pull_requests": "write",
					"statuses": "write"
				},
				"events": [
					"issues",
					"issue_comment",
					"label",
					"organization",
					"pull_request",
					"pull_request_review",
					"pull_request_review_comment",
					"pull_request_review_thread",
					"release",
					"repository"
				]
			}
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020469049",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4020469049",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4020469049,
			"node_id": "IC_kwDOBLftOs7vo305",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-09T01:03:07Z",
			"updated_at": "2026-03-09T01:03:07Z",
			"body": "I have read the CLA Document and I hereby sign the CLA",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020469049/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020570985",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4020570985",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4020570985,
			"node_id": "IC_kwDOBLftOs7vpQtp",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-09T01:40:08Z",
			"updated_at": "2026-03-09T01:40:08Z",
			"body": "Addressed CodeRabbit feedback: (1) Added itemKey so useItemEventHandlers re-runs when the element is recreated and listeners are re-attached; (2) Made rootElement nullable in useItemElement and removed the double cast in the test.",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4020570985/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4043109098",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4043109098",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4043109098,
			"node_id": "IC_kwDOBLftOs7w_PLq",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-12T00:36:44Z",
			"updated_at": "2026-03-12T00:36:44Z",
			"body": "I have implemented the suggested refactor\r\n\r\n**Changes:**\r\n\r\n- `useItemEventHandlers`: Now takes only (onInputChange, onClick) and returns a stable object { onInputChange, onClick } via useMemo. It no longer takes a ref, root element, or itemKey, and has no useEffect or DOM usage, the hook only provide handlers.\r\n\r\n- `useItemElement`: Now accepts a last parameter `itemEventHandlers `(type `ItemEventHandlers`), In the same `useEffect `that creates the element, it finds inputs (checkbox/text) and buttons inside the element and attaches `itemEventHandlers.onInputChange` and `itemEventHandlers.onClick`. DOM is no longer “forced” to update by `itemKey`\r\n\r\n- `NoteListItem`: It no longer passes a ref into `useItemEventHandlers `or uses `itemKey`.\r\n\r\n- `Types`: Added `ItemEventHandlers `in utils/types.ts for the object returned by `useItemEventHandlers`.\r\n\r\n- `useItemEventHandlers.test.ts`: Since that there are No DOM or refs so I removed `act`.",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4043109098/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4061443290",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4061443290",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4061443290,
			"node_id": "IC_kwDOBLftOs7yFLTa",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-14T21:31:20Z",
			"updated_at": "2026-03-16T00:45:16Z",
			"body": "Hello @personalizedrefrigerator, I did the changes.\r\n- removed useItemEventHandlers.\r\n- refactored `useItemElement `with an `addItemEventListeners` helper returns **cleanup**.\r\n- fixed the ItemEventHandlers type in NoteListItem.\r\n- .md files are note ignored now.",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4061443290/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4064285488",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4064285488",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4064285488,
			"node_id": "IC_kwDOBLftOs7yQBMw",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-16T00:19:46Z",
			"updated_at": "2026-03-16T00:19:46Z",
			"body": "Addressed CodeRabbit: focus-visible no longer triggers a full DOM rebuild.\r\n\r\n`focusVisible` is no longer in the main effect’s dependency array. A second, ref-based effect only adds/removes the `-focus-visible` class on the existing element when `focusVisible` changes. This keeps live DOM state (e.g. text in plugin inputs, active control) intact when tabbing between notes.",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4064285488/reactions",
				"total_count": 1,
				"+1": 1,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4067391983",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4067391983",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4067391983,
			"node_id": "IC_kwDOBLftOs7yb3nv",
			"user": {
				"login": "Pixels57",
				"id": 111073325,
				"node_id": "U_kgDOBp7YLQ",
				"avatar_url": "https://avatars.githubusercontent.com/u/111073325?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/Pixels57",
				"html_url": "https://github.com/Pixels57",
				"followers_url": "https://api.github.com/users/Pixels57/followers",
				"following_url": "https://api.github.com/users/Pixels57/following{/other_user}",
				"gists_url": "https://api.github.com/users/Pixels57/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/Pixels57/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/Pixels57/subscriptions",
				"organizations_url": "https://api.github.com/users/Pixels57/orgs",
				"repos_url": "https://api.github.com/users/Pixels57/repos",
				"events_url": "https://api.github.com/users/Pixels57/events{/privacy}",
				"received_events_url": "https://api.github.com/users/Pixels57/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-16T12:43:11Z",
			"updated_at": "2026-03-16T12:43:11Z",
			"body": "Hello @personalizedrefrigerator, \r\nDo you think that there are other required changes?\r\nAnd I was wondering if I could open another PR, will that be okay or not as I am a GSOC participant",
			"author_association": "CONTRIBUTOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4067391983/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		},
		{
			"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4067555128",
			"html_url": "https://github.com/laurent22/joplin/pull/14651#issuecomment-4067555128",
			"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/14651",
			"id": 4067555128,
			"node_id": "IC_kwDOBLftOs7ycfc4",
			"user": {
				"login": "personalizedrefrigerator",
				"id": 46334387,
				"node_id": "MDQ6VXNlcjQ2MzM0Mzg3",
				"avatar_url": "https://avatars.githubusercontent.com/u/46334387?v=4",
				"gravatar_id": "",
				"url": "https://api.github.com/users/personalizedrefrigerator",
				"html_url": "https://github.com/personalizedrefrigerator",
				"followers_url": "https://api.github.com/users/personalizedrefrigerator/followers",
				"following_url": "https://api.github.com/users/personalizedrefrigerator/following{/other_user}",
				"gists_url": "https://api.github.com/users/personalizedrefrigerator/gists{/gist_id}",
				"starred_url": "https://api.github.com/users/personalizedrefrigerator/starred{/owner}{/repo}",
				"subscriptions_url": "https://api.github.com/users/personalizedrefrigerator/subscriptions",
				"organizations_url": "https://api.github.com/users/personalizedrefrigerator/orgs",
				"repos_url": "https://api.github.com/users/personalizedrefrigerator/repos",
				"events_url": "https://api.github.com/users/personalizedrefrigerator/events{/privacy}",
				"received_events_url": "https://api.github.com/users/personalizedrefrigerator/received_events",
				"type": "User",
				"user_view_type": "public",
				"site_admin": false
			},
			"created_at": "2026-03-16T13:10:08Z",
			"updated_at": "2026-03-16T13:10:08Z",
			"body": "> Do you think that there are other required changes?\r\n\r\nBased on the code, this pull request looks good to me! I'm planning to test this locally in the next day or two prior to giving this change final approval.\r\n\r\n> And I was wondering if I could open another PR, will that be okay or not as I am a GSOC participant\r\n\r\nPlease do so! This change is just waiting for my final review after local testing.",
			"author_association": "COLLABORATOR",
			"reactions": {
				"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4067555128/reactions",
				"total_count": 0,
				"+1": 0,
				"-1": 0,
				"laugh": 0,
				"hooray": 0,
				"confused": 0,
				"heart": 0,
				"rocket": 0,
				"eyes": 0
			},
			"performed_via_github_app": null
		}
	]
}