Update modals.js
Browse files- static/js/ui/modals.js +64 -15
static/js/ui/modals.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
// static/js/ui/modals.js
|
| 2 |
|
| 3 |
import { dom } from './dom.js';
|
|
@@ -5,23 +6,19 @@ import { dom } from './dom.js';
|
|
| 5 |
let currentGalleryImages = [];
|
| 6 |
let currentGalleryIndex = 0;
|
| 7 |
|
|
|
|
| 8 |
const createMenuItem = (options) => {
|
| 9 |
const { action, format = '', text, icon, isDanger = false, type = 'button' } = options;
|
| 10 |
const element = document.createElement(type);
|
| 11 |
element.className = `menu-item ${isDanger ? 'danger' : ''}`;
|
| 12 |
element.dataset.action = action;
|
| 13 |
if (format) element.dataset.format = format;
|
|
|
|
| 14 |
element.innerHTML = `${icon}<span>${text}</span><div class="hidden w-4 h-4 border-2 border-slate-300 border-t-blue-500 rounded-full animate-spin ml-auto"></div>`;
|
| 15 |
return element;
|
| 16 |
};
|
| 17 |
|
| 18 |
-
|
| 19 |
-
${createMenuItem({ action, format: 'pdf', text: 'تبدیل به PDF', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m.75 12l3 3m0 0l3-3m-3 3v-6m-1.5-9H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>` }).outerHTML}
|
| 20 |
-
${createMenuItem({ action, format: 'docx', text: 'تبدیل به Word', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H15M2.25 3h1.5M2.25 6h1.5M2.25 9h1.5M2.25 12h1.5M2.25 15h1.5M2.25 18h1.5M4.5 21h15a2.25 2.25 0 002.25-2.25V5.25A2.25 2.25 0 0019.5 3h-15A2.25 2.25 0 002.25 5.25v13.5A2.25 2.25 0 004.5 21z" /></svg>` }).outerHTML}
|
| 21 |
-
${createMenuItem({ action, format: 'txt', text: 'تبدیل به Text', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25H12" /></svg>` }).outerHTML}
|
| 22 |
-
${createMenuItem({ action, format: 'html', text: 'تبدیل به HTML', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" /></svg>` }).outerHTML}
|
| 23 |
-
`;
|
| 24 |
-
|
| 25 |
function showImageInGallery(index) {
|
| 26 |
if (index < 0 || index >= currentGalleryImages.length) return;
|
| 27 |
currentGalleryIndex = index;
|
|
@@ -141,35 +138,81 @@ export function toggleHtmlPreviewModal(show, htmlContent = '') {
|
|
| 141 |
}
|
| 142 |
}
|
| 143 |
|
|
|
|
| 144 |
export function showHistoryMenu(event, sessionId) {
|
| 145 |
event.stopPropagation();
|
| 146 |
const menu = dom.historyItemMenu;
|
| 147 |
|
|
|
|
| 148 |
menu.innerHTML = `
|
| 149 |
-
${createMenuItem({
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
<div class="menu-divider"></div>
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
<div class="menu-divider"></div>
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
`;
|
| 155 |
|
| 156 |
menu.dataset.sessionId = sessionId;
|
| 157 |
|
|
|
|
| 158 |
const buttonRect = event.currentTarget.getBoundingClientRect();
|
| 159 |
-
const menuHeight =
|
| 160 |
const margin = 8;
|
| 161 |
|
| 162 |
let top = buttonRect.bottom + margin;
|
| 163 |
let right = window.innerWidth - buttonRect.right;
|
| 164 |
|
|
|
|
| 165 |
if (top + menuHeight > window.innerHeight) {
|
| 166 |
top = buttonRect.top - menuHeight - margin;
|
| 167 |
}
|
| 168 |
|
|
|
|
|
|
|
|
|
|
| 169 |
menu.style.top = `${top}px`;
|
| 170 |
menu.style.right = `${right}px`;
|
| 171 |
menu.style.left = 'auto';
|
| 172 |
-
menu.style.transformOrigin = (top > buttonRect.top) ? '
|
| 173 |
|
| 174 |
menu.classList.add('visible');
|
| 175 |
const closeMenu = () => {
|
|
@@ -189,10 +232,15 @@ export function showMessageMenu(event, messageIndex, activeChat, escapeHTML) {
|
|
| 189 |
const textPart = message.parts.find(p => p.text);
|
| 190 |
const textContent = textPart ? textPart.text : '[محتوای غیر متنی]';
|
| 191 |
|
|
|
|
| 192 |
let menuItemsHtml = '';
|
|
|
|
| 193 |
if (message.role === 'assistant' && textPart) {
|
| 194 |
-
|
| 195 |
-
|
|
|
|
|
|
|
|
|
|
| 196 |
}
|
| 197 |
|
| 198 |
menuItemsHtml += createMenuItem({
|
|
@@ -376,4 +424,5 @@ export function togglePlusRequiredModal(show) {
|
|
| 376 |
modal.classList.add('hidden');
|
| 377 |
}, 300);
|
| 378 |
}
|
| 379 |
-
}
|
|
|
|
|
|
| 1 |
+
// --- START OF FILE modals.js ---
|
| 2 |
// static/js/ui/modals.js
|
| 3 |
|
| 4 |
import { dom } from './dom.js';
|
|
|
|
| 6 |
let currentGalleryImages = [];
|
| 7 |
let currentGalleryIndex = 0;
|
| 8 |
|
| 9 |
+
// تابع کمکی برای ساخت آیتمهای منو
|
| 10 |
const createMenuItem = (options) => {
|
| 11 |
const { action, format = '', text, icon, isDanger = false, type = 'button' } = options;
|
| 12 |
const element = document.createElement(type);
|
| 13 |
element.className = `menu-item ${isDanger ? 'danger' : ''}`;
|
| 14 |
element.dataset.action = action;
|
| 15 |
if (format) element.dataset.format = format;
|
| 16 |
+
// اضافه کردن آیکون و متن + لودینگ مخفی
|
| 17 |
element.innerHTML = `${icon}<span>${text}</span><div class="hidden w-4 h-4 border-2 border-slate-300 border-t-blue-500 rounded-full animate-spin ml-auto"></div>`;
|
| 18 |
return element;
|
| 19 |
};
|
| 20 |
|
| 21 |
+
// تابع نمایش تصویر در گالری (بدون تغییر)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
function showImageInGallery(index) {
|
| 23 |
if (index < 0 || index >= currentGalleryImages.length) return;
|
| 24 |
currentGalleryIndex = index;
|
|
|
|
| 138 |
}
|
| 139 |
}
|
| 140 |
|
| 141 |
+
// *** تابع اصلی که منوی سه نقطه تاریخچه را میسازد (به روز شده) ***
|
| 142 |
export function showHistoryMenu(event, sessionId) {
|
| 143 |
event.stopPropagation();
|
| 144 |
const menu = dom.historyItemMenu;
|
| 145 |
|
| 146 |
+
// تعریف دقیق آیتمها به ترتیب خواسته شده
|
| 147 |
menu.innerHTML = `
|
| 148 |
+
${createMenuItem({
|
| 149 |
+
action: 'rename',
|
| 150 |
+
text: 'تغییر نام گفتگو',
|
| 151 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125" /></svg>`
|
| 152 |
+
}).outerHTML}
|
| 153 |
+
|
| 154 |
<div class="menu-divider"></div>
|
| 155 |
+
|
| 156 |
+
${createMenuItem({
|
| 157 |
+
action: 'convert-chat',
|
| 158 |
+
format: 'pdf',
|
| 159 |
+
text: 'تبدیل به PDF',
|
| 160 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m.75 12l3 3m0 0l3-3m-3 3v-6m-1.5-9H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>`
|
| 161 |
+
}).outerHTML}
|
| 162 |
+
|
| 163 |
+
${createMenuItem({
|
| 164 |
+
action: 'convert-chat',
|
| 165 |
+
format: 'docx',
|
| 166 |
+
text: 'تبدیل به Word',
|
| 167 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H15M2.25 3h1.5M2.25 6h1.5M2.25 9h1.5M2.25 12h1.5M2.25 15h1.5M2.25 18h1.5M4.5 21h15a2.25 2.25 0 002.25-2.25V5.25A2.25 2.25 0 0019.5 3h-15A2.25 2.25 0 002.25 5.25v13.5A2.25 2.25 0 004.5 21z" /></svg>`
|
| 168 |
+
}).outerHTML}
|
| 169 |
+
|
| 170 |
+
${createMenuItem({
|
| 171 |
+
action: 'convert-chat',
|
| 172 |
+
format: 'txt',
|
| 173 |
+
text: 'تبدیل به Text',
|
| 174 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25H12" /></svg>`
|
| 175 |
+
}).outerHTML}
|
| 176 |
+
|
| 177 |
+
${createMenuItem({
|
| 178 |
+
action: 'convert-chat',
|
| 179 |
+
format: 'html',
|
| 180 |
+
text: 'تبدیل به HTML',
|
| 181 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" /></svg>`
|
| 182 |
+
}).outerHTML}
|
| 183 |
+
|
| 184 |
<div class="menu-divider"></div>
|
| 185 |
+
|
| 186 |
+
${createMenuItem({
|
| 187 |
+
action: 'delete',
|
| 188 |
+
text: 'حذف گفتگو',
|
| 189 |
+
icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" /></svg>`,
|
| 190 |
+
isDanger: true
|
| 191 |
+
}).outerHTML}
|
| 192 |
`;
|
| 193 |
|
| 194 |
menu.dataset.sessionId = sessionId;
|
| 195 |
|
| 196 |
+
// تنظیم موقعیت منو
|
| 197 |
const buttonRect = event.currentTarget.getBoundingClientRect();
|
| 198 |
+
const menuHeight = 350; // ارتفاع تخمینی منو با گزینههای بیشتر
|
| 199 |
const margin = 8;
|
| 200 |
|
| 201 |
let top = buttonRect.bottom + margin;
|
| 202 |
let right = window.innerWidth - buttonRect.right;
|
| 203 |
|
| 204 |
+
// اگر پایین صفحه جا نیست، منو را به سمت بالا باز کن
|
| 205 |
if (top + menuHeight > window.innerHeight) {
|
| 206 |
top = buttonRect.top - menuHeight - margin;
|
| 207 |
}
|
| 208 |
|
| 209 |
+
// جلوگیری از بیرون زدن از بالای صفحه
|
| 210 |
+
if (top < 0) top = 10;
|
| 211 |
+
|
| 212 |
menu.style.top = `${top}px`;
|
| 213 |
menu.style.right = `${right}px`;
|
| 214 |
menu.style.left = 'auto';
|
| 215 |
+
menu.style.transformOrigin = (top > buttonRect.top) ? 'top right' : 'bottom right';
|
| 216 |
|
| 217 |
menu.classList.add('visible');
|
| 218 |
const closeMenu = () => {
|
|
|
|
| 232 |
const textPart = message.parts.find(p => p.text);
|
| 233 |
const textContent = textPart ? textPart.text : '[محتوای غیر متنی]';
|
| 234 |
|
| 235 |
+
// برای منوی پیام تکی هم همان گزینهها را با استفاده از تابع کمکی میسازیم
|
| 236 |
let menuItemsHtml = '';
|
| 237 |
+
|
| 238 |
if (message.role === 'assistant' && textPart) {
|
| 239 |
+
menuItemsHtml += createMenuItem({ action: 'convert-message', format: 'pdf', text: 'تبدیل به PDF', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m.75 12l3 3m0 0l3-3m-3 3v-6m-1.5-9H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>` }).outerHTML;
|
| 240 |
+
menuItemsHtml += createMenuItem({ action: 'convert-message', format: 'docx', text: 'تبدیل به Word', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H15M2.25 3h1.5M2.25 6h1.5M2.25 9h1.5M2.25 12h1.5M2.25 15h1.5M2.25 18h1.5M4.5 21h15a2.25 2.25 0 002.25-2.25V5.25A2.25 2.25 0 0019.5 3h-15A2.25 2.25 0 002.25 5.25v13.5A2.25 2.25 0 004.5 21z" /></svg>` }).outerHTML;
|
| 241 |
+
menuItemsHtml += createMenuItem({ action: 'convert-message', format: 'txt', text: 'تبدیل به Text', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25H12" /></svg>` }).outerHTML;
|
| 242 |
+
menuItemsHtml += createMenuItem({ action: 'convert-message', format: 'html', text: 'تبدیل به HTML', icon: `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" /></svg>` }).outerHTML;
|
| 243 |
+
menuItemsHtml += '<div class="menu-divider"></div>';
|
| 244 |
}
|
| 245 |
|
| 246 |
menuItemsHtml += createMenuItem({
|
|
|
|
| 424 |
modal.classList.add('hidden');
|
| 425 |
}, 300);
|
| 426 |
}
|
| 427 |
+
}
|
| 428 |
+
// --- END OF FILE modals.js ---
|