Mobile/Thinking Update
This commit is contained in:
parent
86fb8551fe
commit
db7a92e457
|
|
@ -2,6 +2,8 @@ rojo-chat-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
background: #0f1117;
|
background: #0f1117;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,6 +74,7 @@ rojo-chat-panel {
|
||||||
|
|
||||||
.rcp-history {
|
.rcp-history {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 14px 12px;
|
padding: 14px 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class RojoChatPanel extends HTMLElement
|
||||||
_md: { render: ( s: string ) => string } | null = null;
|
_md: { render: ( s: string ) => string } | null = null;
|
||||||
_rojos: RojoEntry[] = [];
|
_rojos: RojoEntry[] = [];
|
||||||
_selectedPath = '';
|
_selectedPath = '';
|
||||||
|
_thinkingInterval: ReturnType<typeof setInterval> | null = null;
|
||||||
|
|
||||||
connectedCallback(): void
|
connectedCallback(): void
|
||||||
{
|
{
|
||||||
|
|
@ -85,6 +86,11 @@ class RojoChatPanel extends HTMLElement
|
||||||
if ( e.key === 'Enter' && !e.shiftKey ) { e.preventDefault(); this._send(); }
|
if ( e.key === 'Enter' && !e.shiftKey ) { e.preventDefault(); this._send(); }
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
inputText.addEventListener( 'focus', () =>
|
||||||
|
{
|
||||||
|
setTimeout( () => inputText.scrollIntoView( { behavior: 'smooth', block: 'nearest' } ), 300 );
|
||||||
|
} );
|
||||||
|
|
||||||
picker.addEventListener( 'change', () =>
|
picker.addEventListener( 'change', () =>
|
||||||
{
|
{
|
||||||
this._selectedPath = picker.value;
|
this._selectedPath = picker.value;
|
||||||
|
|
@ -164,6 +170,25 @@ class RojoChatPanel extends HTMLElement
|
||||||
catch {}
|
catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_startThinking( bubble: HTMLElement ): void
|
||||||
|
{
|
||||||
|
const frames = [ '.', '..', '...', 'thinking', '.', '..', '...', 'imagining' ];
|
||||||
|
let i = 0;
|
||||||
|
bubble.textContent = frames[ 0 ];
|
||||||
|
this._thinkingInterval = setInterval( () =>
|
||||||
|
{
|
||||||
|
i = ( i + 1 ) % frames.length;
|
||||||
|
bubble.textContent = frames[ i ];
|
||||||
|
}, 250 );
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopThinking(): void
|
||||||
|
{
|
||||||
|
if ( this._thinkingInterval === null ) return;
|
||||||
|
clearInterval( this._thinkingInterval );
|
||||||
|
this._thinkingInterval = null;
|
||||||
|
}
|
||||||
|
|
||||||
async _send(): Promise<void>
|
async _send(): Promise<void>
|
||||||
{
|
{
|
||||||
if ( this._sending ) return;
|
if ( this._sending ) return;
|
||||||
|
|
@ -187,10 +212,11 @@ class RojoChatPanel extends HTMLElement
|
||||||
|
|
||||||
const assistantBubble = document.createElement( 'div' );
|
const assistantBubble = document.createElement( 'div' );
|
||||||
assistantBubble.className = 'rcp-assistant-bubble';
|
assistantBubble.className = 'rcp-assistant-bubble';
|
||||||
assistantBubble.textContent = '…';
|
|
||||||
history.appendChild( assistantBubble );
|
history.appendChild( assistantBubble );
|
||||||
history.scrollTop = history.scrollHeight;
|
history.scrollTop = history.scrollHeight;
|
||||||
|
|
||||||
|
this._startThinking( assistantBubble );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const body: Record<string, string> = { id: this._conversationId, message: text };
|
const body: Record<string, string> = { id: this._conversationId, message: text };
|
||||||
|
|
@ -231,6 +257,11 @@ class RojoChatPanel extends HTMLElement
|
||||||
const msg = JSON.parse( trimmed ) as { type: string; text?: string };
|
const msg = JSON.parse( trimmed ) as { type: string; text?: string };
|
||||||
if ( msg.type === 'CHAT' && msg.text )
|
if ( msg.type === 'CHAT' && msg.text )
|
||||||
{
|
{
|
||||||
|
if ( !markdown )
|
||||||
|
{
|
||||||
|
this._stopThinking();
|
||||||
|
assistantBubble.innerHTML = '';
|
||||||
|
}
|
||||||
await typeText( msg.text, piece =>
|
await typeText( msg.text, piece =>
|
||||||
{
|
{
|
||||||
markdown += piece;
|
markdown += piece;
|
||||||
|
|
@ -243,10 +274,11 @@ class RojoChatPanel extends HTMLElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !markdown ) assistantBubble.textContent = '(no response)';
|
if ( !markdown ) { this._stopThinking(); assistantBubble.textContent = '(no response)'; }
|
||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
|
this._stopThinking();
|
||||||
assistantBubble.textContent = '(error: could not reach Rojo)';
|
assistantBubble.textContent = '(error: could not reach Rojo)';
|
||||||
console.error( err );
|
console.error( err );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue