@fhryurygfgdf
לא ראיתי, זה כנראה היה ביחד
תבדוק בפוסטים הקודמים מהפוסט בקישור והלאה...
מוטל 2
-
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים! -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@fhryurygfgdf
לא !!!!
בקשתי ממנו שיעדכן את הקוד בפוסט הראשון..
ומה איתך, הצלחת? -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@יודע-ומייבין
אולי תעדכן כבר את הקוד בסקריפט שלך... -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@fhryurygfgdf
תעדכן את הקוד שאני כתבתי
בפוסט זה
https://mitmachim.top/post/1236183 -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@fhryurygfgdf
איזה קוד מעודכן אצלך? -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@יודע-ומייבין
בהצלחה!!!!!
ותודה רבה.
אני לא מתמצא באנדרואיד כלל... -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@fhryurygfgdf בהגדרות התוספים
-
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים! -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@7090866
מעניין, כנראה תקלה טכנית אצלך עכשיו בפורום..
קרה לעוד מישהו? -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@ברווז-הסגול
איזה קוד התקנת? -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@משה-הצדיק
אשרת את זה?

-
שיתוף | תוסף דפדפן לקבלת SMS ממערכת ימות המשיח@צדיק-וטוב-לו-0
זה פשוט מדהים כל השיפורים...
רק הייתי שמח כשתתפנה להוסיף אפשרות של 'טיפול בהמשך'
וכן סימון כלא נקרא שישאר ההתראה בחוץ של המספר על סמל התוסף...תודה רבה...
-
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@רפאל-0 הסתדרת?
-
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@YOLEVI
גם אני מנוטפר
תמחק את הקוד שם ותעתיק את זה או שתפתח סקריפט חדש

תעשה שמור, ולאח"מ תרענן את הדף של מתמחים... -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים! -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@יאיר-דניאל
להיפך מטרתו לנתח את השאלה שלך ולענות
ולא להטיף לך מוסר.... -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@יודע-ומייבין
אני מחזיר את הפוסט -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!@מה-זה-משנה-אה
מה הבעיה שזה עשה לך? -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!דרך אגב, קרה למישהו תקלות בקוד שלי?
אשמח לקבל הערות,
כי לפי הנראה זה עובד מצויין.... -
המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!שלום וברכה,
כיון שזה היה חשוב לי, ישבתי על הקוד שלו שעות, וב"ה הצלחתי לעשות לו שטיפת מוח, כולל כמה וכמה שיפורים {כגון הסטוריית בקשות, וקישורים לחיצים וכן אפשרות לגרור את החלון ממקום למקום, וכן הוספתי אפשרות להוספת קבצים או תמונות לדיוק השאלה או הבקשה}.
הקוד המתוקן בספויילר:
// ==UserScript== // @name מתמחים טופ + בינה טופ - עוזר AI מושלם עם תמיכה בקבצים, תמונות והדבקה ישירה // @namespace https://mitmachim.top/ // @version 23.0.0 // @description עוזר AI צף עם תמיכה בצירוף והדבקת קבצים ותמונות, חיפוש משתמשים ואשכולות, היסטוריית שיחות וגרירת חלון // @author you // @match https://mitmachim.top/* // @match https://bina.top/* // @icon https://mitmachim.top/favicon.ico // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @connect generativelanguage.googleapis.com // @connect mitmachim.top // @connect bina.top // @run-at document-end // ==/UserScript== (function () { 'use strict'; function getSiteOrigin() { const host = location.hostname.toLowerCase(); if (host === 'bina.top' || host.endsWith('.bina.top')) { return 'https://bina.top'; } return 'https://mitmachim.top'; } const SITE_ORIGIN = getSiteOrigin(); const SITE_HOST = new URL(SITE_ORIGIN).hostname; const K = { apiKey: 'mt_ai_gemini_key', context: 'mt_ai_context', persona: 'mt_ai_persona', sessions: 'mt_ai_sessions_list', currentSessionId: 'mt_ai_current_session_id' }; const get = (k, d = '') => GM_getValue(k, d); const set = (k, v) => GM_setValue(k, v); function request(details) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ ...details, onload: resolve, onerror: () => reject(new Error('שגיאת רשת')), ontimeout: () => reject(new Error('זמן קצוב עבר')) }); }); } async function fetchText(url) { const res = await request({ method: 'GET', url, timeout: 25000 }); if (res.status < 200 || res.status >= 300) throw new Error('שגיאה בטעינת נתונים'); return res.responseText; } function htmlToText(root) { if (!root) return ''; const clone = root.cloneNode(true); clone.querySelectorAll('script,style').forEach(x => x.remove()); clone.querySelectorAll('a[href]').forEach(a => { try { const href = new URL(a.getAttribute('href'), SITE_ORIGIN).href; const label = (a.textContent || '').trim(); const replacement = label && label !== href ? `${label} (${href})` : href; a.replaceWith(document.createTextNode(' ' + replacement + ' ')); } catch {} }); clone.querySelectorAll('br').forEach(br => br.replaceWith(document.createTextNode('\n'))); clone.querySelectorAll('p,div,li,blockquote,tr,h1,h2,h3,h4,h5,h6').forEach(b => { b.appendChild(document.createTextNode('\n')); }); return (clone.textContent || '') .replace(/[ \t]+/g, ' ') .replace(/ *\n */g, '\n') .replace(/\n{3,}/g, '\n\n') .trim(); } function extractSearchHits(data) { const arr = data?.posts || data?.matches || data?.results || []; if (!Array.isArray(arr)) return []; return arr.map(p => { const topic = p.topic || p; const title = topic?.title || p.title || '(ללא כותרת)'; const slug = topic?.slug || p.slug; const tid = topic?.tid || p.tid; let url = ''; if (slug) url = `${SITE_ORIGIN}/topic/${slug}`; else if (tid) url = `${SITE_ORIGIN}/topic/${tid}`; return { title, url }; }).filter(h => h.url); } async function legacySearchScrape(query) { try { const url = `${SITE_ORIGIN}/search?term=${encodeURIComponent(query)}`; const html = await fetchText(url); const doc = new DOMParser().parseFromString(html, 'text/html'); doc.querySelectorAll('script,style,nav,header,footer').forEach(x => x.remove()); const results = []; doc.querySelectorAll('a[href*="/topic/"]').forEach(a => { if (results.length >= 6) return; const href = a.getAttribute('href'); const text = (a.textContent || '').trim(); if (href && text && text.length > 3) { try { const absolute = new URL(href, url).href; if (!results.some(r => r.url === absolute)) { results.push({ title: text, url: absolute }); } } catch {} } }); return results; } catch { return []; } } async function searchUserProfile(query) { query = String(query || '').trim(); if (!query) return ''; try { const apiUrl = `${SITE_ORIGIN}/api/users?query=${encodeURIComponent(query)}&page=1`; const raw = await fetchText(apiUrl); const data = JSON.parse(raw); const users = data?.users || []; if (!users.length) return ''; let block = `משתמשים שנמצאו בפורום עבור "${query}":\n\n`; users.slice(0, 5).forEach(u => { const username = u.username || 'לא ידוע'; const fullname = u.fullname ? ` (${u.fullname})` : ''; const reputation = u.reputation !== undefined ? u.reputation : 'לא ידוע'; const postCount = u.postcount !== undefined ? u.postcount : 'לא ידוע'; const profileUrl = `${SITE_ORIGIN}/user/${u.userslug || username}`; block += `- משתמש: ${username}${fullname}\n קישור לפרופיל: ${profileUrl}\n מוניטין: ${reputation} | הודעות: ${postCount}\n\n`; }); return block; } catch { return ''; } } async function quickForumSearch(query) { query = String(query || '').trim(); if (!query) return ''; let userBlock = ''; if (query.includes('משתמש') || query.includes('פרופיל') || query.includes('מוניטין')) { const cleanName = query.replace(/משתמש|פרופיל|מוניטין|של/g, '').trim(); if (cleanName) { userBlock = await searchUserProfile(cleanName); } } let hits = []; try { const apiUrl = `${SITE_ORIGIN}/api/search?term=${encodeURIComponent(query)}`; const raw = await fetchText(apiUrl); const data = JSON.parse(raw); hits = extractSearchHits(data); } catch { hits = []; } if (!hits.length) { hits = await legacySearchScrape(query); } let block = userBlock ? userBlock + '\n' : ''; if (hits.length > 0) { const seen = new Set(); const uniqueHits = hits.filter(h => { if (seen.has(h.url)) return false; seen.add(h.url); return true; }); const topResults = uniqueHits.slice(0, 3); const enriched = await Promise.all(topResults.map(async r => { const snippet = await fetchTopicSnippet(r.url); return { ...r, snippet }; })); block += `תוצאות חיפוש אשכולות בפורום ${SITE_HOST} עבור "${query}":\n\n`; enriched.forEach((r, i) => { block += `--- נושא ${i + 1}: ${r.title} ---\nקישור מלא: ${r.url}\n`; block += r.snippet ? `תוכן הנושא:\n${r.snippet}\n\n` : '(לא ניתן היה לשלוף את תוכן הנושא)\n\n'; }); } return block; } async function fetchTopicSnippet(url, maxChars = 1400) { try { const html = await fetchText(url); const doc = new DOMParser().parseFromString(html, 'text/html'); doc.querySelectorAll('script,style,nav,header,footer,aside,form').forEach(x => x.remove()); const postEls = Array.from(doc.querySelectorAll('[component="post"]')); let text = ''; if (postEls.length) { const parts = postEls.slice(0, 8).map((post, i) => { const contentEl = post.querySelector('[component="post/content"]') || post; const authorEl = post.querySelector('[component="user/username"]') || post.querySelector('a[href*="/user/"]'); const author = authorEl ? authorEl.textContent.trim() : ''; const postText = htmlToText(contentEl); return postText ? `[פוסט ${i + 1}${author ? ' מאת ' + author : ''}]\n${postText}` : ''; }).filter(Boolean); text = parts.join('\n\n'); } if (!text) { const container = doc.querySelector('[component="topic"]') || doc.querySelector('main') || doc.body; text = htmlToText(container); } if (text.length > maxChars) text = text.slice(0, maxChars) + '\n...[הטקסט קוצץ]'; return text; } catch { return ''; } } function getPageContext() { try { const main = document.querySelector('[component="topic"]') || document.querySelector('main') || document.body; let text = htmlToText(main); if (text.length > 1500) { text = text.slice(0, 1500) + '\n...[הטקסט קוצץ]'; } return `אתר: ${SITE_HOST}\nכותרת: ${document.title}\nתוכן העמוד:\n${text}`; } catch { return ''; } } const MODEL_CANDIDATES = ['gemini-3.6-flash', 'gemini-3.5-flash-lite', 'gemini-2.5-flash-lite']; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function callGeminiWithModel(model, key, body) { const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${encodeURIComponent(key)}`; const res = await request({ method: 'POST', url, headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(body), timeout: 30000 }); let data; try { data = JSON.parse(res.responseText); } catch { throw new Error('תשובת השרת אינה תקינה.'); } if (res.status < 200 || res.status >= 300) { const err = new Error(data?.error?.message || `שגיאה (${res.status})`); err.status = res.status; throw err; } const parts = data?.candidates?.[0]?.content?.parts || []; const answer = parts.filter(p => !p.thought).map(p => p.text || '').join(''); const finishReason = data?.candidates?.[0]?.finishReason; if (finishReason === 'MAX_TOKENS' && answer.trim()) { return answer + '\n\n⚠️ (התשובה נקטעה עקב מגבלת אורך)'; } return answer || '(לא התקבלה תשובה)'; } async function callGemini(history, searchResults) { const key = get(K.apiKey, '').trim(); if (!key) throw new Error('לא הוגדר מפתח API בהגדרות.'); let systemText = `אתה עוזר AI לפורום ${SITE_HOST}. ענה בעברית ברורה, מדויקת ולעניין. באפשרותך לחפש ולהציג גם פרופילים, מוניטין ונתוני משתמשים בפורום במידת הצורך.`; const persona = get(K.persona, ''); if (persona) systemText += '\n\n' + persona; if (get(K.context, true)) { const context = getPageContext(); if (context) systemText += '\n\n' + context; } if (searchResults) { systemText += '\n\nמידע שנמצא בחיפוש בפורום ובמשתמשים:\n' + searchResults; } const contents = history.map(m => { const parts = []; if (m.fileData) { parts.push({ inlineData: { mimeType: m.fileData.mimeType, data: m.fileData.data } }); } parts.push({ text: m.text }); return { role: m.role === 'model' ? 'model' : 'user', parts }; }); const body = { contents, generationConfig: { maxOutputTokens: 2500 } }; if (systemText) { body.systemInstruction = { parts: [{ text: systemText }] }; } let lastError; for (const model of MODEL_CANDIDATES) { for (let attempt = 0; attempt < 2; attempt++) { try { return await callGeminiWithModel(model, key, body); } catch (e) { lastError = e; const retryable = e.status === 503 || e.status === 429; if (retryable && attempt === 0) { await sleep(1200); continue; } break; } } } throw lastError || new Error('כל המודלים נכשלו.'); } // --- UI Elements & Styling --- const style = document.createElement('style'); style.textContent = ` #bina-ai-button { position:fixed; bottom:22px; left:22px; width:58px; height:58px; border-radius:50%; border:0; background:linear-gradient(135deg,#4f8cff,#7c5cff); color:white; font-size:27px; cursor:pointer; z-index:999999; box-shadow:0 5px 20px rgba(0,0,0,.3); } #bina-ai-panel { position:fixed; left:22px; bottom:92px; width:400px; max-width:92vw; height:560px; max-height:80vh; background:white; border-radius:15px; overflow:hidden; display:none; flex-direction:column; z-index:999999; box-shadow:0 10px 40px rgba(0,0,0,.3); direction:rtl; font-family:Arial,sans-serif; border:1px solid #ddd; } #bina-ai-panel.open { display:flex; } #bina-ai-panel.fullscreen { inset:0; width:100vw; height:100vh; max-width:none; max-height:none; border-radius:0; } #bina-ai-header { padding:11px; background:linear-gradient(135deg,#4f8cff,#7c5cff); color:white; font-weight:bold; display:flex; justify-content:space-between; align-items:center; cursor:move; user-select:none; } #bina-ai-header button { border:0; background:transparent; color:white; font-size:15px; cursor:pointer; margin-right:4px; } #bina-ai-new-btn { background: #ffffff !important; color: #4f8cff !important; padding: 4px 10px; border-radius: 8px; font-size: 12px !important; font-weight: bold; margin-left: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.15); transition: all 0.2s; cursor: pointer; } #bina-ai-new-btn:hover { background: #f0f4ff !important; transform: translateY(-1px); } #bina-ai-info { padding:6px 10px; font-size:11px; background:#fafafa; border-bottom:1px solid #eee; color:#666; display:flex; justify-content:space-between; align-items:center; } #bina-ai-messages { flex:1; overflow-y:auto; padding:10px; background:#f5f6fa; display:flex; flex-direction:column; gap:8px; } .bina-ai-msg { padding:9px 11px; border-radius:10px; max-width:88%; font-size:13px; line-height:1.5; white-space:pre-wrap; word-break:break-word; } .bina-ai-user { align-self:flex-end; background:#4f8cff; color:white; } .bina-ai-model { align-self:flex-start; background:white; border:1px solid #ddd; color:#222; } .bina-ai-error { align-self:center; color:#a00000; background:#ffe3e3; border:1px solid #f0b0b0; } .bina-ai-step { align-self:center; color:#444; background:#eef2ff; font-size:11px; } .bina-ai-msg a { color:#2a5fd6; text-decoration:underline; word-break:break-all; } .bina-ai-user a { color:#eaf1ff; } #bina-ai-inputbar { display:flex; gap:6px; padding:8px; border-top:1px solid #ddd; background: #fff; align-items: center; } #bina-ai-input { flex:1; resize:none; height:40px; border:1px solid #ddd; border-radius:8px; padding:8px; font-family:inherit; } #bina-ai-send { border:0; border-radius:8px; padding:0 14px; background:#4f8cff; color:white; font-weight:bold; cursor:pointer; height:40px; } #bina-ai-file-btn { border:0; border-radius:8px; width:40px; height:40px; background:#f0f2f5; color:#555; font-size:18px; cursor:pointer; display:flex; align-items:center; justify-content:center; } #bina-ai-file-btn:hover { background:#e4e6eb; } #bina-file-indicator { font-size: 11px; color: #4f8cff; padding: 2px 10px; background: #eef2ff; display: none; align-items: center; justify-content: space-between; border-bottom: 1px solid #ddd; } #bina-ai-settings { position:fixed; inset:0; display:none; align-items:center; justify-content:center; background:rgba(0,0,0,.45); z-index:1000000; } #bina-ai-settings.open { display:flex; } #bina-ai-settings-box { width:460px; max-width:92vw; max-height:88vh; overflow:auto; background:white; border-radius:15px; padding:18px; direction:rtl; font-family:Arial,sans-serif; } .bina-provider { border:1px solid #ddd; border-radius:10px; padding:10px; margin-bottom:9px; } .bina-provider-title { font-weight:bold; margin-bottom:8px; } .bina-provider input[type=password] { width:100%; box-sizing:border-box; padding:6px; margin-top:5px; border:1px solid #ddd; border-radius:6px; } .bina-field { margin-top:10px; } .bina-field label { display:block; font-weight:bold; font-size:12px; margin-bottom:5px; } .bina-field textarea { width:100%; box-sizing:border-box; padding:8px; border:1px solid #ddd; border-radius:8px; } .bina-buttons { display:flex; justify-content:flex-end; gap:8px; margin-top:15px; } .bina-buttons button { padding:8px 16px; border:0; border-radius:8px; cursor:pointer; } #bina-ai-save { background:#4f8cff; color:white; } .session-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 10px; border-bottom: 1px solid #eee; font-size: 13px; } .session-item:hover { background: #f8f9fa; } .session-title { cursor: pointer; color: #2a5fd6; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: 10px; font-weight: 500; } .session-title:hover { text-decoration: underline; } .session-actions button { background: #ff4d4d; color: white; border: none; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 11px; margin-right: 4px; } .session-actions button.load-btn { background: #4f8cff; } `; document.head.appendChild(style); const button = document.createElement('button'); button.id = 'bina-ai-button'; button.textContent = '🤖'; button.title = `עוזר AI — ${SITE_HOST}`; document.body.appendChild(button); const panel = document.createElement('div'); panel.id = 'bina-ai-panel'; panel.innerHTML = ` <div id="bina-ai-header"> <div style="display:flex; align-items:center;"> <span>🤖 עוזר AI</span> <button id="bina-ai-new-btn" title="התחל שיחה חדשה">💬 שיחה חדשה</button> </div> <div> <button id="bina-ai-settings-btn" title="הגדרות והיסטוריית שיחות">⚙️</button> <button id="bina-ai-fullscreen" title="מסך מלא">⛶</button> <button id="bina-ai-close" title="סגור">✕</button> </div> </div> <div id="bina-ai-info"> <div>🌐 מחובר ל-${SITE_HOST}</div> <div> <label><input type="checkbox" id="bina-ai-context"> הקשר עמוד</label> </div> </div> <div id="bina-file-indicator"> <span id="bina-file-name">📎 קובץ צורף</span> <button id="bina-remove-file" style="background:none; border:none; color:#a00000; cursor:pointer; font-weight:bold;">הסר ✕</button> </div> <div id="bina-ai-messages"></div> <div id="bina-ai-inputbar"> <input type="file" id="bina-ai-file-input" style="display:none;" /> <button id="bina-ai-file-btn" type="button" title="צירוף קובץ או תמונה">📎</button> <textarea id="bina-ai-input" placeholder="שאל שאלה, חפש אשכול, בדוק משתמש או הדבק תמונה/קובץ (Ctrl+V)..."></textarea> <button id="bina-ai-send" type="button">שלח</button> </div> `; document.body.appendChild(panel); // --- Dragging Logic --- const header = document.querySelector('#bina-ai-header'); let isDragging = false, startX, startY, initialX, initialY; header.addEventListener('mousedown', e => { if (e.target.tagName === 'BUTTON') return; isDragging = true; startX = e.clientX; startY = e.clientY; const rect = panel.getBoundingClientRect(); initialX = rect.left; initialY = rect.top; panel.style.bottom = 'auto'; panel.style.left = initialX + 'px'; panel.style.top = initialY + 'px'; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }); function onMouseMove(e) { if (!isDragging) return; const dx = e.clientX - startX; const dy = e.clientY - startY; panel.style.left = (initialX + dx) + 'px'; panel.style.top = (initialY + dy) + 'px'; } function onMouseUp() { isDragging = false; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } // --- File Attachment & Paste Logic --- let attachedFile = null; const fileInput = document.querySelector('#bina-ai-file-input'); const fileBtn = document.querySelector('#bina-ai-file-btn'); const fileIndicator = document.querySelector('#bina-file-indicator'); const fileNameSpan = document.querySelector('#bina-file-name'); const removeFileBtn = document.querySelector('#bina-remove-file'); const input = document.querySelector('#bina-ai-input'); fileBtn.onclick = () => fileInput.click(); function processFile(file) { if (!file) return; const reader = new FileReader(); reader.onload = function (uploadEvent) { const base64Data = uploadEvent.target.result.split(',')[1]; attachedFile = { mimeType: file.type || 'application/octet-stream', data: base64Data, name: file.name || 'קובץ מודבק' }; fileNameSpan.textContent = `📎 ${attachedFile.name} צורף בהצלחה`; fileIndicator.style.display = 'flex'; }; reader.readAsDataURL(file); } fileInput.onchange = (e) => { processFile(e.target.files[0]); }; // תמיכה בהדבקת קובץ/תמונה ישירות לתיבת הטקסט (Ctrl + V) input.addEventListener('paste', (e) => { const items = (e.clipboardData || e.originalEvent.clipboardData).items; for (let index in items) { const item = items[index]; if (item.kind === 'file') { const blob = item.getAsFile(); if (blob) { e.preventDefault(); processFile(blob); break; } } } }); removeFileBtn.onclick = () => { attachedFile = null; fileInput.value = ''; fileIndicator.style.display = 'none'; }; // --- Sessions Management Logic --- let sessions = []; try { sessions = JSON.parse(get(K.sessions, '[]')); if (!Array.isArray(sessions)) sessions = []; } catch (e) { sessions = []; } let currentSessionId = get(K.currentSessionId, ''); let history = []; function saveSessionsToStorage() { set(K.sessions, JSON.stringify(sessions)); set(K.currentSessionId, currentSessionId); } function startNewSession() { const newId = 'session_' + Date.now(); const newSession = { id: newId, title: 'שיחה חדשה', history: [] }; sessions.unshift(newSession); if (sessions.length > 20) sessions.pop(); currentSessionId = newId; history = []; saveSessionsToStorage(); renderMessages(); welcome(); renderSessionsList(); } function loadSession(id) { const found = sessions.find(s => s.id === id); if (found) { currentSessionId = found.id; history = [...found.history]; saveSessionsToStorage(); renderMessages(); if (history.length === 0) welcome(); renderSessionsList(); } } function deleteSession(id) { sessions = sessions.filter(s => s.id !== id); if (currentSessionId === id) { if (sessions.length > 0) { loadSession(sessions[0].id); } else { startNewSession(); } } else { saveSessionsToStorage(); renderSessionsList(); } } // --- Settings & History Modal --- const settings = document.createElement('div'); settings.id = 'bina-ai-settings'; settings.innerHTML = ` <div id="bina-ai-settings-box"> <h3>⚙️ הגדרות והיסטוריית שיחות</h3> <div style="font-size:11px;color:#777;margin-bottom:12px">האתר הנוכחי: <b>${SITE_HOST}</b></div> <div class="bina-provider"> <div class="bina-provider-title">🔵 Gemini API Key</div> <div style="font-size:11px;margin-bottom:3px;color:#555;">מפתח API:</div> <input type="password" id="gemini-key" placeholder="הכנס כאן את המפתח"> </div> <div class="bina-field"><label>הנחיות אישיות</label><textarea id="bina-persona" placeholder="לדוגמה: ענה בקצרה..."></textarea></div> <div class="bina-field" style="margin-top:15px;"> <label>📜 היסטוריית שיחות שמורות</label> <div id="bina-sessions-container" style="max-height:180px; overflow-y:auto; border:1px solid #ddd; border-radius:6px; margin-top:5px; background:#fafafa;"></div> </div> <div class="bina-buttons"><button id="bina-cancel">סגור</button><button id="bina-ai-save">שמור הגדרות</button></div> </div> `; document.body.appendChild(settings); function renderSessionsList() { const container = document.querySelector('#bina-sessions-container'); if (!container) return; if (sessions.length === 0) { container.innerHTML = '<div style="padding:10px; font-size:12px; color:#777; text-align:center;">אין שיחות שמורות</div>'; return; } container.innerHTML = ''; sessions.forEach(s => { const item = document.createElement('div'); item.className = 'session-item'; if (s.id === currentSessionId) { item.style.background = '#eef2ff'; item.style.fontWeight = 'bold'; } const titleSpan = document.createElement('span'); titleSpan.className = 'session-title'; titleSpan.textContent = s.title || 'שיחה ללא כותרת'; titleSpan.title = s.title; titleSpan.onclick = () => { loadSession(s.id); settings.classList.remove('open'); }; const actionsDiv = document.createElement('div'); actionsDiv.className = 'session-actions'; const loadBtn = document.createElement('button'); loadBtn.className = 'load-btn'; loadBtn.textContent = 'המשך'; loadBtn.onclick = () => { loadSession(s.id); settings.classList.remove('open'); }; const delBtn = document.createElement('button'); delBtn.textContent = 'מחק'; delBtn.onclick = () => { deleteSession(s.id); }; actionsDiv.appendChild(loadBtn); actionsDiv.appendChild(delBtn); item.appendChild(titleSpan); item.appendChild(actionsDiv); container.appendChild(item); }); } function loadSettings() { document.querySelector('#gemini-key').value = get(K.apiKey, ''); document.querySelector('#bina-persona').value = get(K.persona, ''); document.querySelector('#bina-ai-context').checked = get(K.context, true); renderSessionsList(); } function saveSettings() { set(K.apiKey, document.querySelector('#gemini-key').value.trim()); set(K.persona, document.querySelector('#bina-persona').value.trim()); set(K.context, document.querySelector('#bina-ai-context').checked); settings.classList.remove('open'); } document.querySelector('#bina-ai-settings-btn').onclick = () => { loadSettings(); settings.classList.add('open'); }; document.querySelector('#bina-cancel').onclick = () => settings.classList.remove('open'); document.querySelector('#bina-ai-save').onclick = saveSettings; document.querySelector('#bina-ai-new-btn').onclick = () => { startNewSession(); }; const messagesContainer = document.querySelector('#bina-ai-messages'); const sendButton = document.querySelector('#bina-ai-send'); function escapeHtml(str) { return String(str) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>'); } function linkify(escapedText) { const urlRegex = /(https?:\/\/[^\s<>"')]+)/g; return escapedText.replace(urlRegex, raw => { const trimmed = raw.replace(/[).,;:!?]+$/, ''); const trailing = raw.slice(trimmed.length); return `<a href="${trimmed}" target="_blank" rel="noopener noreferrer">${trimmed}</a>${trailing}`; }); } function renderMessages() { messagesContainer.innerHTML = ''; history.forEach(m => { const type = m.role === 'user' ? 'bina-ai-user' : 'bina-ai-model'; const div = document.createElement('div'); div.className = 'bina-ai-msg ' + type; let contentHtml = linkify(escapeHtml(m.text)).replace(/\n/g, '<br>'); if (m.fileData && m.fileData.name) { contentHtml = `📎 <b>[קובץ: ${m.fileData.name}]</b><br>` + contentHtml; } div.innerHTML = contentHtml; messagesContainer.appendChild(div); }); messagesContainer.scrollTop = messagesContainer.scrollHeight; } function addMessage(text, type, fileInfo = null) { const div = document.createElement('div'); div.className = 'bina-ai-msg ' + type; let contentHtml = linkify(escapeHtml(text)).replace(/\n/g, '<br>'); if (fileInfo && fileInfo.name) { contentHtml = `📎 <b>[קובץ: ${fileInfo.name}]</b><br>` + contentHtml; } div.innerHTML = contentHtml; messagesContainer.appendChild(div); messagesContainer.scrollTop = messagesContainer.scrollHeight; return div; } function welcome() { addMessage(`שלום! 🤖\nאני עוזר ה-AI של ${SITE_HOST}.\n\nשאל אותי כל שאלה, חפש אשכולות, בדוק פרופילים או צרף/הדבק קובץ ותמונה!`, 'bina-ai-model'); if (!get(K.apiKey)) { addMessage('⚠️ עדיין לא הוגדר מפתח API. פתח ⚙️ והוסף.', 'bina-ai-error'); } } button.onclick = () => panel.classList.toggle('open'); document.querySelector('#bina-ai-close').onclick = () => panel.classList.remove('open'); document.querySelector('#bina-ai-fullscreen').onclick = () => panel.classList.toggle('fullscreen'); async function send() { const text = input.value.trim(); const currentFile = attachedFile; if (!text && !currentFile) return; if (!get(K.apiKey)) { addMessage('⚠️ אין מפתח API פעיל. פתח ⚙️ והגדר.', 'bina-ai-error'); return; } if (!currentSessionId || sessions.length === 0) { startNewSession(); } const messageText = text || 'צורף קובץ לעיון'; addMessage(messageText, 'bina-ai-user', currentFile); history.push({ role: 'user', text: messageText, fileData: currentFile ? { mimeType: currentFile.mimeType, data: currentFile.data, name: currentFile.name } : null }); input.value = ''; attachedFile = null; fileInput.value = ''; fileIndicator.style.display = 'none'; sendButton.disabled = true; const currentSession = sessions.find(s => s.id === currentSessionId); if (currentSession && currentSession.title === 'שיחה חדשה') { currentSession.title = messageText.slice(0, 25) + (messageText.length > 25 ? '...' : ''); } const stepMsg = addMessage('🔎 מחפש בנתוני הפורום והמשתמשים...', 'bina-ai-step'); try { const searchResults = await quickForumSearch(messageText); stepMsg.remove(); const pending = addMessage('🤖 מנתח תשובה...', 'bina-ai-model'); const answer = await callGemini(history, searchResults); pending.remove(); addMessage(answer, 'bina-ai-model'); history.push({ role: 'model', text: answer, fileData: null }); if (currentSession) { currentSession.history = [...history]; saveSessionsToStorage(); } } catch (e) { stepMsg.remove(); addMessage('⚠️ ' + (e?.message || String(e)), 'bina-ai-error'); } finally { sendButton.disabled = false; input.focus(); } } sendButton.onclick = send; input.addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }); GM_registerMenuCommand('⚙️ הגדרות עוזר AI', () => { loadSettings(); settings.classList.add('open'); }); if (sessions.length > 0) { if (!currentSessionId || !sessions.some(s => s.id === currentSessionId)) { currentSessionId = sessions[0].id; } loadSession(currentSessionId); } else { startNewSession(); } })();כמה תמונות מהעוזר גרסת "חפרן" שעשיתי:


