Chat / static /js /main.js
Jan2000's picture
Update main.js
d909246 unverified
raw
history blame
30.2 kB
// static/js/main.js
import * as state from './state.js';
import * as api from './api.js';
import * as db from './db.js';
// New UI module imports
import { dom } from './ui/dom.js';
import * as chatUI from './ui/chat.js';
import * as modalUI from './ui/modals.js';
import * as toolUI from './ui/tools.js';
import * as ttsUI from './ui/tts.js';
let currentUserStatus = {
isPremium: false,
hasBeenChecked: false,
fingerprint: null
};
const MAX_CHAT_SESSIONS = 150;
function checkUserPremiumStatus() {
return currentUserStatus.isPremium;
}
async function handleFileSelection(event) {
const file = event.target.files[0];
if (!file) return;
chatUI.showFileUploading(file.name);
dom.submitButton.disabled = true;
try {
const uploadedFileData = await api.processAndUploadFile(file);
state.setAttachedFile(uploadedFileData);
chatUI.showFileReady(file.name, file.type, uploadedFileData.blobUrl);
} catch (error) {
console.error("خطا در پردازش فایل:", error);
chatUI.showFileError(error.message);
} finally {
event.target.value = '';
toolUI.toggleFilePopupMenu(false);
dom.submitButton.disabled = false;
dom.messageInput.dispatchEvent(new Event('input'));
}
}
function handleNewChat() {
if (state.chatSessions.length >= MAX_CHAT_SESSIONS) {
state.chatSessions.pop();
}
const newSession = { id: Date.now().toString(), title: 'چت جدید', messages: [], showThoughts: false };
state.chatSessions.unshift(newSession);
state.setActiveChatId(newSession.id);
chatUI.renderActiveChat();
chatUI.renderHistoryList();
toolUI.updateToolsButton(null);
state.setActiveToolPrefix(null);
state.setActiveTool(null);
state.saveSessions();
ttsUI.clearAllCache();
ttsUI.stopAudio();
}
function getFullChatText(session) {
if (!session || !session.messages) return "";
return session.messages
.map(msg => {
const prefix = msg.role === 'user' ? 'کاربر' : 'مدل';
const textContent = msg.parts?.find(p => p.text)?.text || '[محتوای غیر متنی]';
return `${prefix}:\n${textContent}`;
})
.join('\n\n---\n\n');
}
function handlePremiumFeatureClick(element) {
if (checkUserPremiumStatus()) {
return true;
}
const parentContainer = element.closest('.premium-locked-item');
if (parentContainer) {
parentContainer.classList.add('animate-premium-lock');
setTimeout(() => {
parentContainer.classList.remove('animate-premium-lock');
}, 800);
}
modalUI.togglePremiumFeatureModal(true);
return false;
}
document.addEventListener('DOMContentLoaded', async () => {
await db.initDB();
await db.cleanupOldFiles();
chatUI.initTheme();
ttsUI.initTtsPlayer();
state.loadSessions();
currentUserStatus.fingerprint = await api.getBrowserFingerprint();
if (state.chatSessions.length > MAX_CHAT_SESSIONS) {
state.chatSessions.length = MAX_CHAT_SESSIONS;
state.saveSessions();
}
if (state.chatSessions.length === 0 || !state.getActiveChat()) {
handleNewChat();
} else {
state.setActiveChatId(state.activeChatId || state.chatSessions[0].id);
chatUI.renderActiveChat();
chatUI.renderHistoryList();
}
chatUI.setupMobileKeyboardFix();
dom.newChatButton.addEventListener('click', handleNewChat);
dom.menuButton.addEventListener('click', () => modalUI.toggleSidebar(true));
dom.sidebarOverlay.addEventListener('click', () => modalUI.toggleSidebar(false));
dom.deleteAllChatsButton.addEventListener('click', () => {
modalUI.showConfirmModal('آیا از حذف تمام چت‌ها مطمئن هستید؟', () => {
state.setChatSessions([]);
state.setActiveChatId(null);
state.saveSessions();
handleNewChat();
modalUI.toggleSidebar(false);
});
});
dom.settingsButton.addEventListener('click', () => {
modalUI.updateSettingsUI(checkUserPremiumStatus());
modalUI.toggleSettingsModal(true);
});
dom.settingsModal.addEventListener('click', (e) => {
if (e.target === dom.settingsModal) modalUI.toggleSettingsModal(false);
});
dom.themeToggle.addEventListener('change', (e) => {
const newTheme = e.target.checked ? 'dark' : 'light';
localStorage.setItem('theme', newTheme);
chatUI.applyTheme(newTheme);
});
dom.toolsButton.addEventListener('click', (e) => {
if (dom.toolsButton.classList.contains('tool-selected')) return;
e.stopPropagation();
const activeChat = state.getActiveChat();
const toggleSwitch = dom.toolsMenu.querySelector('.toggle-switch');
if (activeChat && toggleSwitch) {
toggleSwitch.classList.toggle('active', activeChat.showThoughts);
}
toolUI.toggleToolsMenu(!dom.toolsMenu.classList.contains('active'));
});
dom.attachFileButton.addEventListener('click', (e) => {
e.stopPropagation();
toolUI.toggleFilePopupMenu(!dom.filePopupMenu.classList.contains('active'));
});
dom.toolsMenu.addEventListener('click', (e) => {
const toggleSwitch = e.target.closest('.toggle-switch');
if (toggleSwitch) {
e.stopPropagation();
if (!handlePremiumFeatureClick(toggleSwitch)) return;
toggleSwitch.classList.toggle('active');
const activeChat = state.getActiveChat();
if (activeChat) {
activeChat.showThoughts = toggleSwitch.classList.contains('active');
state.saveSessions();
}
return;
}
const toolItem = e.target.closest('.tool-item');
if (!toolItem) return;
if (toolItem.parentElement.classList.contains('premium-locked-item') && !handlePremiumFeatureClick(toolItem)) {
toolUI.toggleToolsMenu(false);
return;
}
const tool = toolItem.dataset.tool;
const toolName = toolItem.dataset.toolName;
toolUI.toggleToolsMenu(false);
toolUI.updateToolsButton(toolName);
state.setActiveTool(tool);
if (tool === 'deep-think') {
state.setActiveToolPrefix("شما یک محقق حرفه‌ای هستید. با بررسی عمیق و جامع، به سوال زیر یک پاسخ کامل، ساختاریافته و دقیق بدهید: ");
dom.messageInput.placeholder = "موضوع برای تفکر عمیق...";
} else if (tool === 'reasoning') {
state.setActiveToolPrefix("شما یک استدلال‌گر منطقی هستید. با تحلیل گام به گام و ارائه دلایل روشن، به سوال زیر پاسخ دهید: ");
dom.messageInput.placeholder = "موضوع برای استدلال...";
} else {
state.setActiveToolPrefix(null);
state.setActiveTool(null);
}
dom.messageInput.focus();
});
dom.clearToolSelection.addEventListener('click', (e) => {
e.stopPropagation();
state.setActiveToolPrefix(null);
state.setActiveTool(null);
toolUI.updateToolsButton(null);
dom.messageInput.focus();
});
window.addEventListener('click', (e) => {
if (dom.toolsMenu.classList.contains('active') && !dom.toolsMenu.contains(e.target) && !dom.toolsButton.contains(e.target)) {
toolUI.toggleToolsMenu(false);
}
if (dom.filePopupMenu.classList.contains('active') && !dom.filePopupMenu.contains(e.target) && !dom.attachFileButton.contains(e.target)) {
toolUI.toggleFilePopupMenu(false);
}
});
dom.selectImageOption.addEventListener('click', (e) => {
toolUI.toggleFilePopupMenu(false);
if (handlePremiumFeatureClick(e.currentTarget)) dom.imageFileInput.click();
});
dom.selectFileOption.addEventListener('click', (e) => {
toolUI.toggleFilePopupMenu(false);
if (handlePremiumFeatureClick(e.currentTarget)) dom.generalFileInput.click();
});
dom.premiumModalCloseBtn.addEventListener('click', () => modalUI.togglePremiumFeatureModal(false));
dom.premiumFeatureModal.addEventListener('click', (e) => {
if(e.target === dom.premiumFeatureModal) modalUI.togglePremiumFeatureModal(false);
});
dom.premiumModalUpgradeBtn.addEventListener('click', () => {
parent.postMessage({ type: 'NAVIGATE_TO_PREMIUM', payload: { url: chatUI.PREMIUM_URL } }, '*');
modalUI.togglePremiumFeatureModal(false);
});
dom.plusModalCloseBtn.addEventListener('click', () => modalUI.togglePlusRequiredModal(false));
dom.plusRequiredModal.addEventListener('click', (e) => {
if(e.target === dom.plusRequiredModal) modalUI.togglePlusRequiredModal(false);
});
dom.imageFileInput.addEventListener('change', handleFileSelection);
dom.generalFileInput.addEventListener('change', handleFileSelection);
dom.removeImageButton.addEventListener('click', () => {
state.setAttachedFile(null);
chatUI.hideFilePreview();
dom.messageInput.dispatchEvent(new Event('input'));
});
dom.htmlPreviewCloseBtn.addEventListener('click', () => modalUI.toggleHtmlPreviewModal(false));
dom.htmlPreviewOverlay.addEventListener('click', () => modalUI.toggleHtmlPreviewModal(false));
dom.messageForm.addEventListener('submit', async (e) => {
e.preventDefault();
if (state.isGenerating) {
if (state.globalAbortController) state.globalAbortController.abort();
return;
}
if (state.isMessageLimitReached(checkUserPremiumStatus())) {
chatUI.showLimitReachedUpgrade();
return;
}
const activeChat = state.getActiveChat();
if (!activeChat) return;
const userMessageText = dom.messageInput.value.trim();
if (!userMessageText && !state.attachedFile) return;
chatUI.setGeneratingState(true);
let modelBubbleOuterDiv;
try {
const isFirstMessageOfChat = activeChat.messages.length === 0;
if (isFirstMessageOfChat && dom.chatWindow.querySelector('.welcome-screen')) {
dom.chatWindow.querySelector('.welcome-screen').remove();
}
const userParts = [];
let fileAttachedInThisTurn = null;
if (state.attachedFile) {
fileAttachedInThisTurn = { ...state.attachedFile };
userParts.push({
id: fileAttachedInThisTurn.id, blobUrl: fileAttachedInThisTurn.blobUrl,
mimeType: fileAttachedInThisTurn.mimeType, name: fileAttachedInThisTurn.name,
base64Data: fileAttachedInThisTurn.base64Data
});
chatUI.hideFilePreview();
state.setAttachedFile(null);
}
if (userMessageText) userParts.push({ text: userMessageText });
const newUserMessage = { role: 'user', parts: userParts, tool: state.getActiveTool() };
activeChat.messages.push(newUserMessage);
state.incrementMessageCount(checkUserPremiumStatus());
await chatUI.addMessageToUI(newUserMessage, activeChat.messages.length - 1, {isLastUser: true, animate: true});
const modelPlaceholderMessage = { role: 'assistant', isTemporary: true, parts: [] };
activeChat.messages.push(modelPlaceholderMessage);
modelBubbleOuterDiv = await chatUI.addMessageToUI(modelPlaceholderMessage, activeChat.messages.length - 1, {animate: true});
const historyForApi = activeChat.messages.map((msg, index) => {
const isLastMessage = index === activeChat.messages.length - 1;
const isUserMessageJustSent = index === activeChat.messages.length - 2;
if (isUserMessageJustSent) {
return JSON.parse(JSON.stringify(msg));
}
if (isLastMessage) {
return msg;
}
const cleanMsg = { role: msg.role, parts: [] };
if (msg.parts) {
msg.parts.forEach(part => {
if (part.text) {
cleanMsg.parts.push({ text: part.text });
}
});
}
return cleanMsg;
});
const toolPrefix = state.getActiveToolPrefix();
const lastUserMsgInHistory = historyForApi.findLast(m => m.role === 'user');
const textPartInHistory = lastUserMsgInHistory.parts.find(p => p.text);
if (textPartInHistory) {
textPartInHistory.text = (toolPrefix ? toolPrefix : '') + (textPartInHistory.text || '');
} else if (toolPrefix) {
lastUserMsgInHistory.parts.push({ text: toolPrefix });
}
if (isFirstMessageOfChat && userMessageText) {
activeChat.title = userMessageText.substring(0, 30);
chatUI.renderHistoryList();
}
dom.messageInput.value = '';
dom.messageInput.dispatchEvent(new Event('input'));
const activeTool = state.getActiveTool();
if (activeTool === 'deep-think' || activeTool === 'reasoning') {
if (activeTool === 'deep-think') toolUI.updateDeepThinkPanel({ topic: userMessageText || 'فایل ضمیمه شده' }, modelBubbleOuterDiv);
else if (activeTool === 'reasoning') toolUI.updateReasoningPanel({ topic: userMessageText || 'فایل ضمیمه شده' }, modelBubbleOuterDiv);
const progressBar = modelBubbleOuterDiv.querySelector('.bar');
if (progressBar) {
requestAnimationFrame(() => {
progressBar.style.transition = 'width 30s ease-out';
progressBar.style.width = '100%';
});
}
}
// *** تغییر مهم: حذف منطق Retry کلاینت و تایم‌اوت کوتاه ***
// ما فقط یک درخواست می‌زنیم و صبر می‌کنیم. بک‌اند خودش چرخش کلید را انجام می‌دهد.
// به این ترتیب خطای "Server did not respond" که ناشی از عجله کلاینت بود حذف می‌شود.
const response = await api.getChatStream(historyForApi, state.globalAbortController.signal);
await api.readStreamAndDisplay(response, modelBubbleOuterDiv);
} catch (error) {
if (error.name !== 'AbortError') {
console.error("خطا در هنگام تولید پیام:", error);
// اگر خطای واقعی رخ داد، فقط در کنسول لاگ می‌کنیم و به کاربر چیزی نشان نمی‌دهیم یا یک متن عمومی
// طبق خواسته شما که گفتید خطا نشان داده نشود.
if (modelBubbleOuterDiv) {
// اینجا می‌توانیم هیچ کاری نکنیم یا یک متن خالی بگذاریم
// اما برای جلوگیری از گیر کردن، وضعیت را ریست میکنیم
}
} else {
if (modelBubbleOuterDiv && !modelBubbleOuterDiv.querySelector('.message-content')?.innerText.includes('متوقف شد')) {
const contentArea = modelBubbleOuterDiv.querySelector('.message-content') || modelBubbleOuterDiv;
contentArea.innerHTML += '<p class="text-xs text-slate-500 mt-2 text-center p-4">-- عملیات متوقف شد --</p>';
}
}
} finally {
chatUI.resetState();
state.saveSessions();
state.setActiveToolPrefix(null);
state.setActiveTool(null);
toolUI.updateToolsButton(null);
}
});
dom.chatWindow.addEventListener('click', async (e) => {
const button = e.target.closest('.action-button');
if (!button) return;
const action = button.dataset.action;
const messageEntry = button.closest('.message-entry');
if (!messageEntry) return;
const messageIndex = parseInt(messageEntry.dataset.index, 10);
const activeChat = state.getActiveChat();
if (!activeChat || isNaN(messageIndex)) return;
const message = activeChat.messages[messageIndex];
if (action === 'copy') {
const textToCopy = message.parts?.find(p => p.text)?.text || '';
if (textToCopy) navigator.clipboard.writeText(textToCopy).then(() => chatUI.showCopyFeedback(button));
} else if (action === 'like' || action === 'dislike') {
chatUI.handleLikeDislike(button, messageEntry);
} else if (action === 'speak') {
const audioState = ttsUI.getAudioState();
if (audioState.messageIndex === messageIndex && (audioState.status === 'running' || audioState.status === 'suspended')) {
ttsUI.stopAudio();
return;
}
if (ttsUI.hasCacheForMessage(messageIndex)) {
ttsUI.playFromCache(messageIndex, button);
return;
}
const fullText = message.parts?.find(p => p.text)?.text;
if (!fullText) return;
const codeBlockRegex = /```[\s\S]*?```/g;
const textToSpeak = fullText.replace(codeBlockRegex, '').trim();
if (!textToSpeak) {
alert("محتوای متنی برای خواندن وجود ندارد (فقط کد شناسایی شد).");
return;
}
ttsUI.stream(messageIndex, textToSpeak, button);
} else if (action === 'regenerate') {
if (state.isGenerating) return;
chatUI.setGeneratingState(true);
const lastModelMessageIndex = state.findLastIndex(activeChat.messages, msg => msg.role === 'assistant');
if (messageIndex === lastModelMessageIndex) {
ttsUI.clearCacheForMessage(messageIndex);
activeChat.messages.length = messageIndex;
messageEntry.remove();
const lastUserMessageIndex = state.findLastIndex(activeChat.messages, msg => msg.role === 'user');
if (lastUserMessageIndex !== -1) {
const lastUserMessageElement = dom.chatWindow.querySelector(`.message-entry[data-index="${lastUserMessageIndex}"]`);
if (lastUserMessageElement) chatUI.updateMessageActions(lastUserMessageElement, activeChat.messages[lastUserMessageIndex], true, false);
}
const modelPlaceholderMessage = { role: 'assistant', isTemporary: true, parts: [] };
activeChat.messages.push(modelPlaceholderMessage);
const newModelBubble = await chatUI.addMessageToUI(modelPlaceholderMessage, activeChat.messages.length - 1, { animate: true });
try {
const lastUserMessage = activeChat.messages.findLast(m => m.role === 'user');
const lastTool = lastUserMessage?.tool;
const historyForApi = activeChat.messages.map((msg, index) => {
if (index === activeChat.messages.length - 1) return msg;
if (index === activeChat.messages.length - 2) return JSON.parse(JSON.stringify(msg));
const cleanMsg = { role: msg.role, parts: [] };
if (msg.parts) msg.parts.forEach(part => { if (part.text) cleanMsg.parts.push({ text: part.text }); });
return cleanMsg;
});
if (lastTool === 'deep-think' || lastTool === 'reasoning') {
if (lastTool === 'deep-think') toolUI.updateDeepThinkPanel({ topic: lastUserMessage.parts.find(p=>p.text)?.text || 'فایل ضمیمه شده' }, newModelBubble);
if (lastTool === 'reasoning') toolUI.updateReasoningPanel({ topic: lastUserMessage.parts.find(p=>p.text)?.text || 'فایل ضمیمه شده' }, newModelBubble);
const progressBar = newModelBubble.querySelector('.bar');
if (progressBar) {
requestAnimationFrame(() => {
progressBar.style.transition = 'width 30s ease-out';
progressBar.style.width = '100%';
});
}
}
const response = await api.getChatStream(historyForApi, state.globalAbortController.signal);
await api.readStreamAndDisplay(response, newModelBubble);
} catch(error) {
if (error.name !== 'AbortError') console.error("Regeneration failed:", error);
} finally {
chatUI.resetState();
state.saveSessions();
}
} else {
chatUI.resetState();
}
} else if (action === 'edit') {
if (state.isGenerating) return;
const lastUserMessageIndex = state.findLastIndex(activeChat.messages, msg => msg.role === 'user');
if (messageIndex === lastUserMessageIndex) {
const textPart = message.parts.find(p => p.text);
const filePart = message.parts.find(p => p.id);
if (textPart || filePart) {
modalUI.showEditModal(textPart ? textPart.text : '', async (newText) => {
chatUI.setGeneratingState(true);
try {
const allMessagesInDOM = dom.chatWindow.querySelectorAll('.message-entry');
allMessagesInDOM.forEach(msgEl => {
const idx = parseInt(msgEl.dataset.index, 10);
if (idx >= messageIndex) {
ttsUI.clearCacheForMessage(idx);
msgEl.remove();
}
});
activeChat.messages.length = messageIndex;
const newParts = [];
if (filePart) {
const file = await db.getFile(filePart.id);
const blobUrl = URL.createObjectURL(file);
const base64 = await api.processAndUploadFile(file).then(d => d.base64Data);
newParts.push({ ...filePart, blobUrl, base64Data: base64 });
}
if (newText.trim()) newParts.push({ text: newText });
if (newParts.length > 0) {
const editedUserMessage = { role: 'user', parts: newParts };
activeChat.messages.push(editedUserMessage);
await chatUI.addMessageToUI(editedUserMessage, activeChat.messages.length - 1, { isLastUser: true, animate: true });
}
const modelPlaceholderMessage = { role: 'assistant', isTemporary: true, parts: [] };
activeChat.messages.push(modelPlaceholderMessage);
const newModelBubble = await chatUI.addMessageToUI(modelPlaceholderMessage, activeChat.messages.length - 1, { animate: true });
const historyForApi = activeChat.messages.map((msg, index) => {
if (index >= activeChat.messages.length - 2) return JSON.parse(JSON.stringify(msg));
const cleanMsg = { role: msg.role, parts: [] };
if (msg.parts) msg.parts.forEach(part => { if (part.text) cleanMsg.parts.push({ text: part.text }); });
return cleanMsg;
});
const response = await api.getChatStream(historyForApi, state.globalAbortController.signal);
await api.readStreamAndDisplay(response, newModelBubble);
} catch (error) {
if (error.name !== 'AbortError') console.error("Edit failed:", error);
} finally {
chatUI.resetState();
state.saveSessions();
}
});
}
}
}
else if (action === 'show-message-menu') {
modalUI.showMessageMenu(e, messageIndex, activeChat, chatUI.escapeHTML);
}
});
dom.historyItemMenu.addEventListener('click', (e) => {
const button = e.target.closest('.menu-item');
if (!button) return;
const action = button.dataset.action;
const format = button.dataset.format;
const sessionId = dom.historyItemMenu.dataset.sessionId;
const session = state.chatSessions.find(s => s.id === sessionId);
if (!session) return;
if (action === 'rename') {
modalUI.showRenameModal(session.title, (newTitle) => {
session.title = newTitle;
state.saveSessions();
chatUI.renderHistoryList();
});
} else if (action === 'delete') {
modalUI.showConfirmModal(`آیا از حذف گفتگوی "${session.title}" مطمئن هستید؟`, () => {
state.setChatSessions(state.chatSessions.filter(s => s.id !== sessionId));
state.saveSessions();
if (state.activeChatId === sessionId) {
if (state.chatSessions.length > 0) {
state.setActiveChatId(state.chatSessions[0].id);
chatUI.renderActiveChat();
} else {
handleNewChat();
}
}
chatUI.renderHistoryList();
});
} else if (action === 'convert-chat') {
const fullText = getFullChatText(session);
api.convertTextToFile(fullText, format, button);
}
dom.historyItemMenu.classList.remove('visible');
});
dom.messageItemMenu.addEventListener('click', (e) => {
const menu = dom.messageItemMenu;
const closeMenu = () => {
menu.classList.remove('visible');
setTimeout(() => { menu.classList.add('hidden'); }, 300);
};
if (e.target === dom.messageItemMenuOverlay) {
closeMenu();
return;
}
const button = e.target.closest('.menu-item');
if (!button) return;
const action = button.dataset.action;
const format = button.dataset.format;
const messageIndex = parseInt(menu.dataset.messageIndex, 10);
const activeChat = state.getActiveChat();
if (!activeChat || isNaN(messageIndex)) {
closeMenu();
return;
}
const message = activeChat.messages[messageIndex];
if (action === 'delete-message') {
modalUI.showConfirmModal('آیا از حذف این پیام مطمئن هستید؟', () => {
state.deleteMessage(activeChat.id, messageIndex);
ttsUI.clearCacheForMessage(messageIndex);
chatUI.renderActiveChat();
});
} else if (action === 'convert-message') {
const textContent = message.parts?.find(p => p.text)?.text || '';
if (textContent) api.convertTextToFile(textContent, format, button);
else alert('محتوای متنی برای تبدیل وجود ندارد.');
}
closeMenu();
});
dom.messageInput.addEventListener('input', () => {
chatUI.adjustTextareaHeight(dom.messageInput);
if (dom.messageInput.value.trim().length > 0 || state.attachedFile) {
dom.submitButton.classList.add('active');
} else {
dom.submitButton.classList.remove('active');
}
});
dom.editInput.addEventListener('input', () => {
chatUI.adjustTextareaHeight(dom.editInput);
});
window.addEventListener('message', (event) => {
if (event.data && event.data.type === 'USER_DATA_RESPONSE_SIMPLE_CHECK') {
const PREMIUM_PAGE_ID = '1149636';
let isUserPremium = false;
if (event.data.payload) {
try {
const userObject = JSON.parse(event.data.payload);
if (userObject && userObject.isLogin && userObject.accessible_pages) {
if (userObject.accessible_pages.includes(PREMIUM_PAGE_ID) || userObject.accessible_pages.includes(parseInt(PREMIUM_PAGE_ID))) {
isUserPremium = true;
}
}
} catch (e) { console.error("Error parsing user data from parent:", e); }
}
currentUserStatus.isPremium = isUserPremium;
currentUserStatus.hasBeenChecked = true;
if (!dom.settingsModal.classList.contains('hidden')) {
modalUI.updateSettingsUI(isUserPremium);
}
}
});
parent.postMessage({ type: 'REQUEST_USER_DATA_SIMPLE_CHECK' }, '*');
});
window.handleSuggestionClick = chatUI.handleSuggestionClick;