Skip to content

Add click-outside behavior to message bar emoji picker - #1078

Merged
JamesPHoughton merged 5 commits into
mainfrom
copilot/fix-emoji-picker-behavior
Oct 30, 2025
Merged

Add click-outside behavior to message bar emoji picker#1078
JamesPHoughton merged 5 commits into
mainfrom
copilot/fix-emoji-picker-behavior

Conversation

Copilot AI commented Oct 30, 2025

Copy link
Copy Markdown
Contributor
  • Explore repository structure and understand the issue
  • Identify the difference between MessageBubble and TextBar emoji picker implementations
  • Add click-outside functionality to TextBar emoji picker (matching MessageBubble implementation)
  • Verify linting passes for the changes
  • Address code review feedback (match MessageBubble.jsx pattern)
  • Final code review
  • Run security checks (0 vulnerabilities found)
  • Restore accidentally deleted install-docker.sh file

Summary

Successfully implemented click-outside functionality for the message bar emoji picker to match the behavior of the reaction emoji picker.

Changes Made

  • Added pickerRef using useRef(null) to track the emoji picker container in TextBar.jsx
  • Added React.useEffect() hook that listens for mousedown events outside the picker
  • Attached the pickerRef to the picker container div
  • Event listener is properly cleaned up when component unmounts or picker closes
  • Restored etherpad/install-docker.sh that was accidentally deleted

Implementation Details

The implementation follows the exact same pattern as MessageBubble.jsx (lines 24-39), ensuring consistency in behavior. When the user clicks outside the emoji picker, it will now close automatically, providing the same user experience as the reaction emoji picker.

Security Summary

No security vulnerabilities detected by CodeQL analysis.

Testing

  • ✅ Linting passes with no errors
  • ✅ Implementation matches MessageBubble.jsx pattern
  • ✅ Security scan completed with 0 alerts
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: Click outside message bar emoji picker to close</issue_title>
<issue_description>### What happened?

When you use the emoji picker to respond to a message in the chat interface, if you decide not to click one of the emoji, you can just click outside the picker and it'll go away.

Currently, this behavior doesn't happen for the picker in the message bar, so we should update that code to be analogous to how it's done for the reaction emoji picker.

What browsers do you see the problem on?

  • Firefox
  • Chrome
  • Safari
  • Microsoft Edge

What operating system do you see the problem on?

  • Windows
  • Mac
  • Linux

How did we discover the bug?

  • Reported by participant
  • Observed on Sentry
  • Found in dev

Priority

Inconvenience for participants</issue_description>

<agent_instructions>Don't add unnecessary code, use clear inline documentation so that somebody new to the code can easily understand what we're doing and why.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits October 30, 2025 16:21
Co-authored-by: JamesPHoughton <4304478+JamesPHoughton@users.noreply.github.com>
Co-authored-by: JamesPHoughton <4304478+JamesPHoughton@users.noreply.github.com>
Co-authored-by: JamesPHoughton <4304478+JamesPHoughton@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix emoji picker to close when clicking outside Add click-outside behavior to message bar emoji picker Oct 30, 2025
Copilot AI requested a review from JamesPHoughton October 30, 2025 16:28

@JamesPHoughton JamesPHoughton left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot - please don't delete install-docker.sh

Co-authored-by: JamesPHoughton <4304478+JamesPHoughton@users.noreply.github.com>
@JamesPHoughton
JamesPHoughton marked this pull request as ready for review October 30, 2025 19:35

Copilot AI commented Oct 30, 2025

Copy link
Copy Markdown
Contributor Author

@copilot - please don't delete install-docker.sh

Restored in commit 3f6cc9b. The file was accidentally deleted during the initial commit.

@github-actions

Copy link
Copy Markdown
/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/Call.jsx
   38:19  error  Do not nest ternary expressions                                                                        no-nested-ternary
  151:5   error  Do not nest ternary expressions                                                                        no-nested-ternary
  202:32  error  Unexpected block statement surrounding arrow body; move the returned value immediately after the '=>'  arrow-body-style
  266:18  error  Do not use Array index in keys                                                                         react/no-array-index-key

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/chat/Chat.jsx
  32:7  warning  React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/ConditionalRender.jsx
  39:10  error  'tickTock' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/IdleProvider.jsx
   56:6   warning  React Hook useEffect has a missing dependency: 'resetTimer'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
  120:57  error    ''' can be escaped with '&apos;', '&lsquo;', '&#39;', '&rsquo;'                                                react/no-unescaped-entities

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/Markdown.jsx
  17:6  error  Unnecessary escape character: !  no-useless-escape

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/SharedNotepad.jsx
  26:6  warning  React Hook useEffect has missing dependencies: 'defaultText', 'game', and 'record'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/KitchenTimer.jsx
  9:10  error  'tickTock' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/Qualtrics.jsx
  54:10  error  'state' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/TrainingVideo.jsx
  61:6  warning  React Hook useEffect has missing dependencies: 'timer?.elapsed' and 'url'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Consent.jsx
  129:6  warning  React Hook useEffect has a missing dependency: 'player'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Countdown.jsx
  8:21  error  Use default import syntax to import 'ReactCountdown'  import/no-named-default

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/CameraCheck.jsx
  96:6  warning  React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/LoopbackCheck.jsx
  132:34  error    Return values from promise executor functions cannot be read                                               no-promise-executor-return
  162:6   warning  React Hook useEffect has a missing dependency: 'player'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/MicCheck.jsx
  118:6  warning  React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/01_Normal_Paths_Omnibus.js
  174:34  error  'actualOrder' is already declared in the upper scope on line 155 column 13  no-shadow
  201:31  error  'newOrder' is already declared in the upper scope on line 190 column 13     no-shadow

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/03_Text_Chat.js
  200:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions
  215:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/support/sharedSteps.js
  8:9  error  'log' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/getTreatments.js
    8:33  error  Missing file extension for "./preFlight/validateTreatmentFile"  import/extensions
  327:30  error  Unexpected 'await' inside a loop                                no-await-in-loop

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/index.js
  42:43  error  'p' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/postFlight/exportScienceData.js
  4:17  error  'warn' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/dispatch.js
  477:9  error  Unexpected use of continue statement  no-continue

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/preFlightChecks.js
  20:5  error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validateDlConfig.test.js
  2:32  error  Missing file extension for "./validateDlConfig"                                                                            import/extensions
  3:1   error  'vscode' import should occur before import of './validateDlConfig'                                                         import/order
  6:25  error  Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the '=>'  arrow-body-style

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validatePromptFile.test.js
  7:8  error  Missing file extension for "./validatePromptFile"  import/extensions

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/providers/dailyco.js
   37:23  error  Expected to return a value at the end of async function 'createRoom'     consistent-return
  157:23  error  Expected to return a value at the end of async function 'stopRecording'  consistent-return
  229:7   error  Unexpected if as the only statement in an else block                     no-lonely-if

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/utils/logging.js
  1:17  error  'warn' is defined but never used  no-unused-vars
  1:29  error  'log' is defined but never used   no-unused-vars

✖ 39 problems (31 errors, 8 warnings)
  4 errors and 0 warnings potentially fixable with the '--fix' option.

1 similar comment
@github-actions

Copy link
Copy Markdown
/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/Call.jsx
   38:19  error  Do not nest ternary expressions                                                                        no-nested-ternary
  151:5   error  Do not nest ternary expressions                                                                        no-nested-ternary
  202:32  error  Unexpected block statement surrounding arrow body; move the returned value immediately after the '=>'  arrow-body-style
  266:18  error  Do not use Array index in keys                                                                         react/no-array-index-key

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/chat/Chat.jsx
  32:7  warning  React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/ConditionalRender.jsx
  39:10  error  'tickTock' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/IdleProvider.jsx
   56:6   warning  React Hook useEffect has a missing dependency: 'resetTimer'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
  120:57  error    ''' can be escaped with '&apos;', '&lsquo;', '&#39;', '&rsquo;'                                                react/no-unescaped-entities

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/Markdown.jsx
  17:6  error  Unnecessary escape character: !  no-useless-escape

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/SharedNotepad.jsx
  26:6  warning  React Hook useEffect has missing dependencies: 'defaultText', 'game', and 'record'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/KitchenTimer.jsx
  9:10  error  'tickTock' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/Qualtrics.jsx
  54:10  error  'state' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/TrainingVideo.jsx
  61:6  warning  React Hook useEffect has missing dependencies: 'timer?.elapsed' and 'url'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Consent.jsx
  129:6  warning  React Hook useEffect has a missing dependency: 'player'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Countdown.jsx
  8:21  error  Use default import syntax to import 'ReactCountdown'  import/no-named-default

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/CameraCheck.jsx
  96:6  warning  React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/LoopbackCheck.jsx
  132:34  error    Return values from promise executor functions cannot be read                                               no-promise-executor-return
  162:6   warning  React Hook useEffect has a missing dependency: 'player'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/MicCheck.jsx
  118:6  warning  React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/01_Normal_Paths_Omnibus.js
  174:34  error  'actualOrder' is already declared in the upper scope on line 155 column 13  no-shadow
  201:31  error  'newOrder' is already declared in the upper scope on line 190 column 13     no-shadow

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/03_Text_Chat.js
  200:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions
  215:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/support/sharedSteps.js
  8:9  error  'log' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/getTreatments.js
    8:33  error  Missing file extension for "./preFlight/validateTreatmentFile"  import/extensions
  327:30  error  Unexpected 'await' inside a loop                                no-await-in-loop

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/index.js
  42:43  error  'p' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/postFlight/exportScienceData.js
  4:17  error  'warn' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/dispatch.js
  477:9  error  Unexpected use of continue statement  no-continue

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/preFlightChecks.js
  20:5  error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validateDlConfig.test.js
  2:32  error  Missing file extension for "./validateDlConfig"                                                                            import/extensions
  3:1   error  'vscode' import should occur before import of './validateDlConfig'                                                         import/order
  6:25  error  Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the '=>'  arrow-body-style

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validatePromptFile.test.js
  7:8  error  Missing file extension for "./validatePromptFile"  import/extensions

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/providers/dailyco.js
   37:23  error  Expected to return a value at the end of async function 'createRoom'     consistent-return
  157:23  error  Expected to return a value at the end of async function 'stopRecording'  consistent-return
  229:7   error  Unexpected if as the only statement in an else block                     no-lonely-if

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/utils/logging.js
  1:17  error  'warn' is defined but never used  no-unused-vars
  1:29  error  'log' is defined but never used   no-unused-vars

✖ 39 problems (31 errors, 8 warnings)
  4 errors and 0 warnings potentially fixable with the '--fix' option.

@cypress

cypress Bot commented Oct 30, 2025

Copy link
Copy Markdown

Deliberation    Run #1790

Run Properties:  status check passed Passed #1790  •  git commit 3f6cc9bb06: Restore install-docker.sh that was accidentally deleted
Project Deliberation
Branch Review copilot/fix-emoji-picker-behavior
Run status status check passed Passed #1790
Run duration 06m 42s
Commit git commit 3f6cc9bb06: Restore install-docker.sh that was accidentally deleted
Committer copilot-swe-agent[bot]
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 1
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 16
View all changes introduced in this branch ↗︎

@JamesPHoughton
JamesPHoughton merged commit 49f3357 into main Oct 30, 2025
7 checks passed
@JamesPHoughton
JamesPHoughton deleted the copilot/fix-emoji-picker-behavior branch October 30, 2025 20:00
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.

[Bug]: Click outside message bar emoji picker to close

2 participants