implemented the quick reply chips for the conversation for better user experience. - #21
implemented the quick reply chips for the conversation for better user experience.#21farhanp1502 wants to merge 9 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe PR adds profile editing, localized profile fields, a reusable ChangesVoice chat profile and quick replies
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant DynamicVoiceChat
participant UserProfileModal
participant updateUserProfileApi
participant Chip
participant handleSendMessage
User->>DynamicVoiceChat: Open profile control
DynamicVoiceChat->>UserProfileModal: Provide profile data and form schema
User->>UserProfileModal: Save profile fields
UserProfileModal->>DynamicVoiceChat: Return form values
DynamicVoiceChat->>updateUserProfileApi: PATCH profile data
updateUserProfileApi-->>DynamicVoiceChat: Return updated profile data
User->>Chip: Select quick-reply label
Chip->>handleSendMessage: Submit label as override text
handleSendMessage->>DynamicVoiceChat: Record consumed bot message
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 3347-3351: Update the quick-reply onClick handler near
handleSendMessage to acquire a synchronous per-message lock before awaiting the
send, keyed by lastBotMsg?.updated_at or the equivalent bot-message identifier.
Ignore subsequent clicks while that message is locked, and clear the lock when
handleSendMessage fails so retries remain possible; preserve the existing
successful setQuickReplySentForMsgId behavior.
🪄 Autofix
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 Plus
Run ID: 94fe2c55-5a2d-4bf6-b686-b24a633186cd
📒 Files selected for processing (3)
src/components/Chip/index.jsxsrc/constants/dynamic-chat.jssrc/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
| onKeyDown={ | ||
| isClickable | ||
| ? (e) => { | ||
| if (e.key === "Enter" || e.key === " ") { |
There was a problem hiding this comment.
Why this condition is used?
e.key === " "
There was a problem hiding this comment.
this is when used is focused on the chip and try to press spacebar then it uses auto reply happens,
however i will remove the condition and only keep enter for now.
| event.stopPropagation() | ||
| } | ||
| // overrideText is used by quick-reply chips to send directly without touching textMessage | ||
| const messageToSend = overrideText ?? textMessage |
There was a problem hiding this comment.
From where is the "textMessage" coming from?
There was a problem hiding this comment.
This is the textMessage from the input field, where the user types their message before it is sent as a prompt to the bot.
| audioRef.current.currentTime = 0 | ||
| } | ||
| if (!textMessage.trim()) return | ||
| if (!messageToSend.trim()) return false |
There was a problem hiding this comment.
trim the value while storing the message to messageToSend key in line 888
| } | ||
| if (showHistorySidebar) { | ||
| const firstMsg = textMessage.trim() | ||
| const firstMsg = messageToSend.trim() |
There was a problem hiding this comment.
Make the respective changes post .trim() change in line 888
| size="sm" | ||
| disabled={hasStartedRecording || isFetchingData || (isSimpleBot === false && strandStep >= stateMachineLength)} | ||
| onClick={async () => { | ||
| const text = typeof chip === "string" ? chip : chip.label ?? chip.text ?? String(chip) |
There was a problem hiding this comment.
Can u check this logic?
if chip is an object when it goes to String(chip)
Is it right?
|
@coderabbitai please review my pr |
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@public/locales/te/translation.json`:
- Around line 115-124: Add the missing recents translation entry to the Telugu
locale alongside the related profile translation keys, using a concise Telugu
label for recent conversations and preserving the existing JSON structure.
In `@src/components/UserProfileModal/index.jsx`:
- Around line 95-104: The FormData invocation in the profile field rendering
must pass the schema-defined labels for state and district instead of relying
only on placeholders. Add labelName using the translated f.labelKey or
f.labelName fallback and pass labelClass as labelCls, matching the other
text-input FormData calls.
In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 244-248: Normalize profile data to a canonical non-empty name in
the session response handling at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L244-L248 and modal
fallback fetch at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2692-L2698, preferring
name with first_name as fallback. After a successful save, update the canonical
name field in src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2711-L2736.
In the profile rendering flow at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2916-L2945, use the
canonical name consistently and fall back to t("user") before indexing the
avatar initial.
🪄 Autofix
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 Plus
Run ID: b0229dee-ed03-472b-ac57-f4a43edf7ecd
📒 Files selected for processing (14)
public/locales/en/translation.jsonpublic/locales/hi/translation.jsonpublic/locales/kn/translation.jsonpublic/locales/or/translation.jsonpublic/locales/ta/translation.jsonpublic/locales/te/translation.jsonsrc/api/endpoints/user.jssrc/components/Chip/index.jsxsrc/components/UserProfileModal/index.jsxsrc/constants/profileForm.jssrc/constants/urls.tssrc/pages/ShikshalokamVoiceChat/dynamic-voice-chat.jssrc/pages/ShikshalokamVoiceChat/shikshaChatStyle.csssrc/utils/session.js
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/Chip/index.jsx
| <FormData | ||
| layOut={f.layOut || 1} | ||
| id={f.id} | ||
| inputType={f.inputType || "text"} | ||
| inputName={f.inputName} | ||
| inputValue={formValues[f.dataKey] || ""} | ||
| inputOnChange={e => handleChange(f.dataKey, e.target.value)} | ||
| placeholder={t(f.placeholderKey || f.placeholder, f.placeholder)} | ||
| inputClass={inputCls} | ||
| /> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Pass labels to the split input controls.
PROFILE_FORM_SCHEMA defines labels for state and district. These FormData calls omit labelName and labelClass, unlike the other text inputs. Placeholders do not provide persistent labels.
Pass t(f.labelKey || f.labelName, f.labelName) and labelCls to FormData.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/UserProfileModal/index.jsx` around lines 95 - 104, The
FormData invocation in the profile field rendering must pass the schema-defined
labels for state and district instead of relying only on placeholders. Add
labelName using the translated f.labelKey or f.labelName fallback and pass
labelClass as labelCls, matching the other text-input FormData calls.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/components/UserProfileModal/index.jsx (1)
66-72: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve unsaved profile edits during parent re-renders.
dynamic-voice-chat.jscreates a newuserDataobject on every parent render. While the modal is open, unrelated voice-chat updates rerun the effect and reset the controlledformValues, which discards unsaved edits. MemoizeuserDataor initialize the form only when its field values change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/UserProfileModal/index.jsx` around lines 66 - 72, Update the initialization effect in UserProfileModal so parent re-renders with a newly created but value-equivalent userData object do not overwrite unsaved formValues while the modal is open. Memoize userData at the caller or gate the effect on actual profile field-value changes, while preserving initialization when the relevant user data changes or the modal is opened.src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js (2)
2726-2734: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winPropagate cleared profile values to local state.
The payload sends empty strings for missing fields, but local stores update only when values are truthy. If a user clears
state, the server can save the empty value whileuserStateretains the old value. The later PDF path readsuserStateand can use stale profile data. Update clearable fields unconditionally after a successful save.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js` around lines 2726 - 2734, Update the successful profile-save handling around setFirstName, setState, and _userData so clearable payload fields are propagated unconditionally, including empty strings. Ensure userState and the corresponding local profile fields reflect cleared name, state, school_name, district, and role values, preventing the PDF path from using stale data.
953-973: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winReturn a successful queue or send result from
handleSendMessage.useChatWebhookqueues messages while the socket isCONNECTING, butsendMessagereturnsfalsefor that queued path and for unavailable sockets.handleSendMessageignores this result and always returnstrue, so a quick reply can become hidden and locked when its message was not accepted. Returntruefor sent or queued messages, and use that result before settingquickReplySentForMsgId.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js` around lines 953 - 973, The handleSendMessage flow must honor the result from sendMessage: capture whether the message was successfully sent or queued, return that result instead of always returning true, and only update quickReplySentForMsgId after a successful result. Preserve the existing text clearing and scroll behavior while preventing quick replies from being dismissed when the socket rejects or cannot queue the message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/components/UserProfileModal/index.jsx`:
- Around line 66-72: Update the initialization effect in UserProfileModal so
parent re-renders with a newly created but value-equivalent userData object do
not overwrite unsaved formValues while the modal is open. Memoize userData at
the caller or gate the effect on actual profile field-value changes, while
preserving initialization when the relevant user data changes or the modal is
opened.
In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 2726-2734: Update the successful profile-save handling around
setFirstName, setState, and _userData so clearable payload fields are propagated
unconditionally, including empty strings. Ensure userState and the corresponding
local profile fields reflect cleared name, state, school_name, district, and
role values, preventing the PDF path from using stale data.
- Around line 953-973: The handleSendMessage flow must honor the result from
sendMessage: capture whether the message was successfully sent or queued, return
that result instead of always returning true, and only update
quickReplySentForMsgId after a successful result. Preserve the existing text
clearing and scroll behavior while preventing quick replies from being dismissed
when the socket rejects or cannot queue the message.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0b4b5be0-2ec7-4c87-b7d6-8f77b95640e4
📒 Files selected for processing (9)
public/locales/en/translation.jsonpublic/locales/hi/translation.jsonpublic/locales/kn/translation.jsonpublic/locales/or/translation.jsonpublic/locales/ta/translation.jsonpublic/locales/te/translation.jsonsrc/components/UserProfileModal/index.jsxsrc/constants/profileForm.jssrc/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
💤 Files with no reviewable changes (5)
- public/locales/hi/translation.json
- public/locales/kn/translation.json
- public/locales/en/translation.json
- public/locales/or/translation.json
- public/locales/ta/translation.json
🚧 Files skipped from review as they are similar to previous changes (2)
- src/constants/profileForm.js
- public/locales/te/translation.json
|
|
||
| const fields = schema.fields || [] | ||
|
|
||
| const wasOpenRef = useRef(false) |
| return | ||
| } | ||
|
|
||
| const justOpened = !wasOpenRef.current |
| if (justOpened || dataChanged) { | ||
| const init = {} | ||
| fields.forEach(field => { | ||
| if (field.type === "split") { |
There was a problem hiding this comment.
are we getting field type as "split"?
|
|
||
| const handleOverlayClick = e => { if (e.target === overlayRef.current) onClose() } | ||
|
|
||
| const inputCls = |
There was a problem hiding this comment.
give full relevant and complete variable names
| return ( | ||
| <div key={field.id} className="mb-3 sm:mb-4"> | ||
| <div className="label-div"> | ||
| <b className={labelCls}>{t(field.labelName, field.labelName)}</b> |
There was a problem hiding this comment.
whats the use of this?
Giving multiple field.labelName, are we passign any dynamic value?
| const handleOpenProfileModal = async () => { | ||
| setShowProfileModal(true) | ||
| // Reuse profileApiData already fetched during validateToken/validateSession to avoid duplicate API calls | ||
| if (!profileApiData || Object.keys(profileApiData).length === 0) { |
There was a problem hiding this comment.
Why this condition check?
| if (canonicalName) setFirstName(canonicalName) | ||
| } | ||
| } catch (error) { | ||
| console.error("Error fetching profile via validateSession:", error) |
There was a problem hiding this comment.
Also if profile fetch fails toast message not required?
| flex-shrink: 0; | ||
| } | ||
|
|
||
| .saathi-popup-user-trigger { |
There was a problem hiding this comment.
dont give specific class names as saathi
Use generic/common names
| onClose={() => setShowProfileModal(false)} | ||
| onLogout={() => { setShowProfileModal(false); handleLogout() }} | ||
| onSave={handleSaveProfile} | ||
| userData={{ |
There was a problem hiding this comment.
This object is used in many place
Try creating a function so that it takes the input object and returns the expected output
USe that function in other places wherever this object structure is being used
| name: payload.name, | ||
| })) | ||
|
|
||
| showNotification({ |
There was a problem hiding this comment.
The auto close changes is done?
Summary by CodeRabbit
New Features
Localization