Changeset 0.17.2 (#77)
This commit is contained in:
@@ -4,6 +4,75 @@
|
||||
// Chat management, send, stream, regenerate, edit, branch,
|
||||
// summarize, per-chat model persistence.
|
||||
|
||||
// ── Chat Input Abstraction ──────────────────
|
||||
// Wraps CM6 editor (when available) or fallback textarea.
|
||||
// All code that reads/writes the message input goes through this.
|
||||
|
||||
const ChatInput = {
|
||||
_editor: null, // CM6 instance, set during init
|
||||
_textarea: null, // fallback textarea element
|
||||
|
||||
getValue() {
|
||||
if (this._editor) return this._editor.getValue();
|
||||
return this._textarea?.value || '';
|
||||
},
|
||||
|
||||
setValue(text) {
|
||||
if (this._editor) {
|
||||
this._editor.setValue(text || '');
|
||||
} else if (this._textarea) {
|
||||
this._textarea.value = text || '';
|
||||
this._textarea.style.height = 'auto';
|
||||
}
|
||||
},
|
||||
|
||||
focus() {
|
||||
if (this._editor) this._editor.focus();
|
||||
else this._textarea?.focus();
|
||||
},
|
||||
|
||||
/** Get the DOM element (for paste listeners, etc.) */
|
||||
getDom() {
|
||||
if (this._editor) return this._editor.getView().contentDOM;
|
||||
return this._textarea;
|
||||
},
|
||||
|
||||
/** Get the wrapper DOM element (for resize, etc.) */
|
||||
getWrapDom() {
|
||||
if (this._editor) return this._editor.getView().dom;
|
||||
return this._textarea;
|
||||
},
|
||||
|
||||
/** Initialize — try CM6, fall back to textarea */
|
||||
init() {
|
||||
this._textarea = document.getElementById('messageInput');
|
||||
const wrap = document.getElementById('messageInputWrap');
|
||||
|
||||
if (window.CM?.chatInput && wrap) {
|
||||
// Hide the textarea, create CM6 editor in its place
|
||||
this._textarea.style.display = 'none';
|
||||
this._editor = CM.chatInput(wrap, {
|
||||
placeholder: 'Send a message...',
|
||||
onSubmit: () => sendMessage(),
|
||||
onChange: () => updateInputTokens(),
|
||||
maxHeight: 200,
|
||||
});
|
||||
DebugLog?.push?.('chat', '[CM6] Chat input initialized');
|
||||
} else {
|
||||
// Fallback: textarea with manual event handling
|
||||
DebugLog?.push?.('chat', '[CM6] Not available — using textarea fallback');
|
||||
this._textarea.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); }
|
||||
});
|
||||
this._textarea.addEventListener('input', function() {
|
||||
this.style.height = 'auto';
|
||||
this.style.height = Math.min(this.scrollHeight, 200) + 'px';
|
||||
updateInputTokens();
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// ── Summarize & Continue ──────────────────
|
||||
|
||||
async function summarizeAndContinue() {
|
||||
@@ -266,7 +335,7 @@ async function newChat() {
|
||||
Tokens._warningDismissed = false;
|
||||
updateContextWarning(); updateChatTokenCount();
|
||||
updateInputTokens();
|
||||
document.getElementById('messageInput').focus();
|
||||
ChatInput.focus();
|
||||
if (window.innerWidth <= 768) {
|
||||
document.getElementById('sidebar').classList.add('collapsed');
|
||||
const ov = document.getElementById('sidebarOverlay');
|
||||
@@ -377,15 +446,13 @@ function startRenameChat(chatId) {
|
||||
// ── Send Message ─────────────────────────────
|
||||
|
||||
async function sendMessage() {
|
||||
const input = document.getElementById('messageInput');
|
||||
const text = input.value.trim();
|
||||
const text = ChatInput.getValue().trim();
|
||||
const hasAttachments = hasStagedAttachments();
|
||||
|
||||
// Need text or attachments, not generating, not blocked by uploads
|
||||
if ((!text && !hasAttachments) || App.isGenerating || isSendBlocked()) return;
|
||||
|
||||
input.value = '';
|
||||
input.style.height = 'auto';
|
||||
ChatInput.setValue('');
|
||||
|
||||
// Snapshot attachment IDs before clearing staged state
|
||||
const attachmentIds = getStagedAttachmentIds();
|
||||
@@ -749,16 +816,8 @@ function _initChatListeners() {
|
||||
UI.toast(`Loaded ${visible} model${visible !== 1 ? 's' : ''}`, 'success');
|
||||
});
|
||||
|
||||
// Input
|
||||
const input = document.getElementById('messageInput');
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); }
|
||||
});
|
||||
input.addEventListener('input', function() {
|
||||
this.style.height = 'auto';
|
||||
this.style.height = Math.min(this.scrollHeight, 200) + 'px';
|
||||
updateInputTokens();
|
||||
});
|
||||
// Input — CM6 or textarea fallback
|
||||
ChatInput.init();
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
|
||||
Reference in New Issue
Block a user