mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-24 03:09:26 +00:00
fix(client): restore the released text for non-text answers too
Only the free-text path sets consumedComposerText, so gating the restore on it discarded the stashed ordinary message whenever the user answered by clicking an option or skipping, while the deletion below ran regardless. The stash is now restored whenever one exists, independently of the reset condition, and it outranks whatever the composer holds since that is the answer draft the submission just consumed.
This commit is contained in:
parent
73af634763
commit
7e15aa750c
2 changed files with 46 additions and 10 deletions
|
|
@ -266,6 +266,39 @@ describe('useAskAnswerMode', () => {
|
|||
expect(mockReleasedComposerText).toEqual({});
|
||||
});
|
||||
|
||||
it('hands the released text back for an option answer too', () => {
|
||||
/** Only the free-text path sets `consumedComposerText`, so gating the
|
||||
* restore on it discarded the stash whenever the user answered by
|
||||
* clicking an option (or skipping) instead of typing. */
|
||||
mockReleasedComposerText = { a1: 'an ordinary unsent message' };
|
||||
const askWithOptions = {
|
||||
actionId: 'a1',
|
||||
question: {
|
||||
question: 'Pick one',
|
||||
options: [
|
||||
{ label: 'Blue', value: 'blue' },
|
||||
{ label: 'Green', value: 'green' },
|
||||
],
|
||||
multiSelect: false,
|
||||
},
|
||||
} as unknown as typeof liveAsk;
|
||||
mockUseGetMessages.mockReturnValue({ data: askWithOptions });
|
||||
mockSubmitAskAnswer.mockImplementation(
|
||||
(_actionId: string, _answer: string, options?: { onSuccess?: () => void }) => {
|
||||
options?.onSuccess?.();
|
||||
},
|
||||
);
|
||||
const { result } = renderHook(() => useAskAnswerMode('conversation-1'));
|
||||
|
||||
act(() => {
|
||||
result.current.submitOption(0);
|
||||
});
|
||||
|
||||
expect(mockSubmitAskAnswer).toHaveBeenCalledWith('a1', 'blue', expect.anything());
|
||||
expect(mockSetComposerText).toHaveBeenLastCalledWith('text', 'an ordinary unsent message');
|
||||
expect(mockReleasedComposerText).toEqual({});
|
||||
});
|
||||
|
||||
it('does not let a delayed answer success clear the composer or selection after navigation', () => {
|
||||
let finishAnswer: (() => void) | undefined;
|
||||
mockUseGetMessages.mockReturnValue({ data: liveAsk });
|
||||
|
|
|
|||
|
|
@ -369,20 +369,23 @@ export default function useAskAnswerMode(conversationId?: string | null) {
|
|||
return next;
|
||||
});
|
||||
/** A successful answer never goes through `collapse`, so the released
|
||||
* text has to be handed back here too or the user's ordinary
|
||||
* message dies with the question. Restored in place of the reset
|
||||
* when one is stashed; the entry is dropped either way so the map
|
||||
* stays bounded. */
|
||||
* text has to be handed back here too or the user's ordinary message
|
||||
* dies with the question.
|
||||
*
|
||||
* Restored whenever one is stashed, independently of the reset
|
||||
* condition below: only the free-text path sets
|
||||
* `consumedComposerText`, so gating on it discarded the stash on an
|
||||
* option click or Skip. The stash also outranks whatever the
|
||||
* composer currently holds, which is the answer draft this
|
||||
* submission just consumed. */
|
||||
const released = releasedComposerTextRef.current[submittedActionId];
|
||||
if (
|
||||
if (released) {
|
||||
currentScope.formContext?.setValue('text', released);
|
||||
} else if (
|
||||
(consumedComposerText || (wasActive && saveDrafts)) &&
|
||||
currentScope.formContext?.getValues('text') === submittedComposerText
|
||||
) {
|
||||
if (released) {
|
||||
currentScope.formContext.setValue('text', released);
|
||||
} else {
|
||||
currentScope.formContext.reset();
|
||||
}
|
||||
currentScope.formContext.reset();
|
||||
}
|
||||
setReleasedComposerText((current) => {
|
||||
if (current[submittedActionId] == null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue