בעקבות כך שלאחרונה ראיתי בפורום יותר ויותר את התופעה המבורכת בה מפתחים מציעים לבנות תוכנה/אפליקציה כלשהי לתועלת המשתמשים חשבתי לעצמי כי יהיה יותר טוב אם תהיה לכך קטגוריה מיוחדת בפורום בשם 'הצעות פיתוח' (או כל שם אחר שתבחרו...) בה יוכלו משתמשי הפורום להציע רעיונות לפיתוח דברים שימושיים ונחוצים, וכן המפתחים יוכלו להציג שם את פרי עבודתם שביקשו המשתמשים.
וכך יצאו כל הצדדים מורווחים: המתכנתים והמפתחים שלפעמים מחפשים רעיונות מה לפתח וכן הסטאז'יסטים שמעוניינים לפתח משהו ימצאו את מבוקשם ורעיונות מספקים ביתר קלות, וכן משתמשי הפורום שזקוקים לעזרה בנושא ייענו על הצד הטוב ביותר.
אז מיזם פיתוח בהתנדבות יוצא לדרך? (אבל מפתחים יקרים, אל תרגישו פרייארים... )
אשמח לשמוע את דעתכם וכמובן את דעת מרנן מנהלי הפורום החשובים שליט"א.

לאצי
-
הצעת ייעול | מיזם התנדבות בפיתוח - מה אתם אומרים? -
הצעת ייעול | קמפיין מתמחים טופ לשרת חזקבהמשך לנושא הזה ולפוסטים הבאים;
לרגל המצב כיום ששרת המערכת קורס בתדירות גבוהה מפני שאין ביכולתו להחזיק כ"כ הרבה משתמשים בו זמנית, מובן מאליו שנדרש (בדחיפות!) להחליף לשרת חזק יותר שיעמוד בעומס שנוצר (ב"ה!) אי לכך, במקום שכל אחד יאמר לעצמו 'מה כבר תועיל התרומה הקטנה שלי...' על הנהלת הפורום לצאת בקמפיין נרחב של גיוס כספים למען הפורום. ומלבד ההרגשה שתתן לתורמים ש 'הכסף שלי לא נבלע אי שם' זה גם יעלה את גודל והיקף התרומות, כי כל אחד רואה 'הנה, עוד סכום כזה ומגיעים לסכום הנדרש לשרת חזק יותר.' וזה כמובן מדרבן לתרום הרבה יותר.
בברכת והריקותי לכם ברכה עד בלי די. (כדי שגם תוכלו לתרום בלי די...)קרדיט ל @סוף-הרחוב על הרעיון כאן, ואל תשכחו 'ללייק' גם אותו.
-
שיתוף | אתר שבניתי ב WIX - רינגטונים להורדה - חסידישע קלאנגעןבניתי לאחרונה אתר חמוד עם פלטפורמת WIX, אתר להורדת רינגטונים חסידיים ועדכניים. לא יודע אם הוא באמת מאה אחוז, אשמח לשמוע הערות והארות, הצעות ייעול וגם על העיצוב.
חסידישע קלאנגען
תודה מראש על הפידבקים... -
להורדה | Noti - תוסף להתראות חכמות בזמן אמת מכל סוגי הפורומיםבהשראת התוסף הנפלא של @אביי ובשילוב התוסף המשלים של @א-ל-0
בניתי (כלומר AI) תוסף מנצח המשלב את כל המעלות מכולם יחד.
הכירו את Noti - תוסף למעקב אחר התראות מכל סוגי הפורומים - הן מבוססי NodeBB (כדוגמת מתמחים, רכבים זל"ז ועוד) והן XenForo (כדוגמת פרוג מורשת מרן ועוד).
ויקרא שמו בישראל Noti אשר הוא כינוי חיבה ל Notification.תכונות מרכזיות
התראות מיידיות על תוכן חדש בפורומים
תמיכה בפורומים מבוססי NodeBB ו-XenForo
אנימציה ייחודית באייקון הדפדפן עם כל התראה
אפשרות להפעלת צליל התראה
הוספה עצמאית של פורומים נוספים
שליטה בתדירות הבדיקות האוטומטית
ממשק בעברית, קל לשימוש
אפשרות השתקה זמנית להתראות
צריכת משאבים נמוכהפורומים נתמכים
מתמחים טופ
תחומים
פורום נטפרי
רכבים זה לזה
פרוג
פורום לתורה
ועוד רבים!יתרונות
עדכונים אוטומטיים גם בהפעלת הדפדפן
התראות חכמות עם תצוגה ויזואלית ברורה
פרטיות מלאה: לא נדרשת הרשמה, התוסף פועל מקומיתשימוש קל
התקן את Noti
הגדר את ההעדפות שלך
קבל התראות חדשות בזמן אמת
התוסף המושלם לחובבי פורומים שרוצים להישאר מעודכנים תמיד!אשמח לשמוע הארות והערות וביקורת בונה.
-
המלצה | חדש בפורום! נושאים שנצפו לאחרונה!בס"ד ולאחר מאמצים משותפים שלי ושל AI... עלה בידינו לכתוב סקריפט לטמפרמונקי להטמעת כפתור 'נצפו לאחרונה' בפורום, כך שניתן יהיה לראות את כל הנושאים שביקרתם בהם ברחבי הפורום.
סקירה כללית:- מראה את כל הנושאים שביקרתם בהם למין הזמן שהתקנתם את הסקריפט.
- כל נושא מופיע פעם אחת בלבד אף אם ביקרתם בו מספר פעמים.
- תיבת חיפוש בין כל הנושאים שנצפו לאחרונה.
// ==UserScript== // @name Mitmachim Top - נצפו לאחרונה (v2.0.4 - Syntax Check) // @namespace http://tampermonkey.net/ // @version 2.0.4 // @description בדיקה מחודשת של תחביר ותפיסת שגיאות מוקדמות. // @author לאצי&AI // @match https://mitmachim.top/* // @icon https://mitmachim.top/assets/uploads/files/1744298283200-font_awesome_5_solid_history.svg.png // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @run-at document-idle // ==/UserScript== (function() { 'use strict'; function ensureDependencies(callback) { let checks = 0; const MAX_CHECKS = 120; const CHECK_INTERVAL = 100; console.log("[LastViewed] Starting dependency check..."); const interval = setInterval(function() { const jQueryReady = typeof $ === 'function'; // More robust check for jQuery const $navList = jQueryReady ? $('nav[component="sidebar/left"] ul#main-nav') : null; const navListReady = $navList && $navList.length > 0; if (navListReady) { clearInterval(interval); console.log(`[LastViewed] Dependencies ($) AND Nav List found after ${checks + 1} checks.`); try { callback(); // Run the main script logic } catch(e) { console.error("[LastViewed] Error executing initialize callback:", e); } } else { checks++; if (checks >= MAX_CHECKS) { clearInterval(interval); console.error(`[LastViewed] Dependency check FAILED after ${MAX_CHECKS} checks (Timeout).`); // Provide detailed status on failure console.error(`[LastViewed] Final Status: jQuery=${typeof $ === 'function'}, NavList Element Found=${jQueryReady ? $('nav[component="sidebar/left"] ul#main-nav').length : 'N/A (jQuery missing)'}`); } } }, CHECK_INTERVAL); } const STORAGE_KEY = 'mitmachim_last_viewed_topics'; const MAX_HISTORY_ITEMS = 20; const TOPIC_URL_PREFIX = 'https://mitmachim.top/topic/'; const DEBOUNCE_DELAY = 300; const styles = ` /* Popup Styles */ #last-viewed-popup { display: flex; flex-direction: column; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 550px; max-height: 80vh; overflow-y: auto; background-color: var(--bs-body-bg, #ffffff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, #dee2e6); box-shadow: 0 5px 15px rgba(0,0,0,0.2); padding: 20px; z-index: 1060; direction: rtl; font-family: "Assistant", sans-serif; font-size: 14px; border-radius: var(--bs-border-radius, 0.375rem); } #last-viewed-popup h2 { flex-shrink: 0; margin-top: 0; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,0.175)); color: var(--bs-heading-color, inherit); text-align: right; font-size: 1.25rem; font-weight: 600; } #last-viewed-popup ul#last-viewed-list { flex-grow: 1; list-style: none; padding: 0; margin: 0; overflow-y: auto; } #last-viewed-popup li { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dashed var(--bs-border-color-translucent, rgba(0,0,0,0.1)); text-align: right; line-height: 1.5; } #last-viewed-popup li:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } #last-viewed-popup a { text-decoration: none; color: var(--bs-link-color, #0d6efd); font-weight: 600; } #last-viewed-popup a:hover { text-decoration: underline; color: var(--bs-link-hover-color, #0a58ca); } #last-viewed-popup .popup-controls { flex-shrink: 0; display: flex; justify-content: space-between; align-items: center; margin-top: 15px; padding-top: 10px; border-top: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,0.175)); } #last-viewed-popup .close-popup-btn, #last-viewed-popup #clear-last-viewed { padding: 0.375rem 0.75rem; font-size: 0.9rem; border-radius: var(--bs-border-radius-sm, 0.25rem); cursor: pointer; text-align: center; vertical-align: middle; user-select: none; border: 1px solid transparent; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } #last-viewed-popup .close-popup-btn { color: var(--bs-secondary-color, #6c757d); background-color: var(--bs-secondary-bg, #e9ecef); border-color: var(--bs-secondary-border, #dee2e6); } #last-viewed-popup .close-popup-btn:hover { background-color: var(--bs-secondary-active-bg, #ced4da); } #last-viewed-popup #clear-last-viewed { color: var(--bs-danger-color, #dc3545); background-color: var(--bs-danger-bg, #f8d7da); border-color: var(--bs-danger-border, #f5c2c7); } #last-viewed-popup #clear-last-viewed:hover { background-color: var(--bs-danger-active-bg, #f1aeb5); } #last-viewed-popup::-webkit-scrollbar { width: 7px; height: 7px; background-color: #e6f9ff; border-radius: 4px; } #last-viewed-popup::-webkit-scrollbar-thumb { background: #99ceff; border-radius: 100px; } #last-viewed-popup::-webkit-scrollbar:hover { width: 12px; } /* Search box styles */ #last-viewed-search-container { flex-shrink: 0; margin-bottom: 15px; } #last-viewed-search { width: 100%; padding: 0.375rem 0.75rem; font-size: 1rem; font-weight: 400; line-height: 1.5; color: var(--bs-body-color); background-color: var(--bs-body-bg); background-clip: padding-box; border: 1px solid var(--bs-border-color); appearance: none; border-radius: var(--bs-border-radius); transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; } #last-viewed-search:focus { border-color: #86b7fe; outline: 0; box-shadow: 0 0 0 0.25rem rgba(13,110,253,.25); } #last-viewed-search::placeholder { color: #6c757d; opacity: 1; } #last-viewed-no-results { text-align: center; color: #6c757d; margin-top: 1rem; display: none; } /* Dynamic Tooltip Styles */ #last-viewed-dynamic-tooltip{position:fixed;background-color:#212529;color:#fff;padding:2px 10px;border-radius:6px;font-size:16px;font-weight:150;font-family:"Assistant",sans-serif;white-space:nowrap;z-index:1100;pointer-events:none;--arrow-size:6px;} #last-viewed-dynamic-tooltip::before{content:"";position:absolute;top:50%;left:100%;margin-top:calc(-1*var(--arrow-size));border-width:var(--arrow-size);border-style:solid;border-color:transparent transparent transparent #212529;} `; GM_addStyle(styles); function getLastViewed() { const data = GM_getValue(STORAGE_KEY, '[]'); try { return JSON.parse(data); } catch (e) { console.error("[LastViewed] Error parsing stored data:", e); return []; } } function setLastViewed(items) { const limitedItems = items.slice(-MAX_HISTORY_ITEMS); GM_setValue(STORAGE_KEY, JSON.stringify(limitedItems)); } function addTopicToHistory(topicTitle, topicUrl) { if (!topicTitle || !topicUrl) return; topicTitle = topicTitle.trim(); const normalizedUrl = topicUrl.split('?')[0].split('#')[0]; let items = getLastViewed(); const existingIndex = items.findIndex(item => item && item.url === normalizedUrl && item.title === topicTitle); if (existingIndex !== -1) { items[existingIndex].timestamp = Date.now(); } else { items = items.filter(item => item && item.url !== normalizedUrl || item.title !== topicTitle); items.push({ title: topicTitle, url: normalizedUrl, timestamp: Date.now() }); } setLastViewed(items); } function getTopicDetailsFromPage() { const currentUrl = window.location.href; if (!currentUrl.startsWith(TOPIC_URL_PREFIX)) { return null; } let title = ''; let $titleSpan = $('h1[component="post/header"] span[component="topic/title"]'); if ($titleSpan.length > 0) { let $tempSpan = $titleSpan.clone(); $tempSpan.find('span[style*="font-size: 10px"]').remove(); title = $tempSpan.text().replace(/\s+/g, ' ').trim(); } if (!title) { title = document.title.replace(/ \| מתמחים טופ.*/, '').trim(); } const normalizedUrl = currentUrl.split('?')[0].split('#')[0]; return { title: title, url: normalizedUrl }; } let debounceTimer; function debounce(func, delay) { return function(...args) { clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { if (typeof func === 'function') { func.apply(this, args); } else { console.error("[LastViewed] Debounced function is not valid at time of execution."); } }, delay); }; } const saveCurrentTopicDebounced = debounce(function() { const currentTopic = getTopicDetailsFromPage(); if (currentTopic && currentTopic.title) { addTopicToHistory(currentTopic.title, currentTopic.url); } }, DEBOUNCE_DELAY); function closePopupAndRemoveListener() { const $popup = $('#last-viewed-popup'); if ($popup.length) { $(document).off('click.closeLastViewed'); $popup.remove(); } } function addClosePopupListener() { $(document).off('click.closeLastViewed'); $(document).on('click.closeLastViewed', function(event) { if (!$('#last-viewed-popup').length) { $(document).off('click.closeLastViewed'); return; } if (!$(event.target).closest('#last-viewed-popup').length && !$(event.target).closest('#last-viewed-btn-li').length) { closePopupAndRemoveListener(); } }); } function filterLastViewedList() { const searchTerm = $('#last-viewed-search').val().toLowerCase().trim(); const $listItems = $('#last-viewed-list li'); let visibleCount = 0; $listItems.each(function() { const $item = $(this); const itemText = $item.find('a').text().toLowerCase(); if (itemText.includes(searchTerm)) { $item.show(); visibleCount++; } else { $item.hide(); } }); if (visibleCount === 0 && $listItems.length > 0) { $('#last-viewed-no-results').show(); } else { $('#last-viewed-no-results').hide(); } } function showLastViewedPopup() { if ($('#last-viewed-popup').length) return; closePopupAndRemoveListener(); console.log("[LastViewed] Opening popup."); let items = getLastViewed(); const uniqueItems = []; const seenTitles = new Set(); for (let i = items.length - 1; i >= 0; i--) { const item = items[i]; if (!seenTitles.has(item.title)) { uniqueItems.push(item); seenTitles.add(item.title); } } items = uniqueItems; const popup = document.createElement('div'); popup.id = 'last-viewed-popup'; const searchContainer = document.createElement('div'); searchContainer.id = 'last-viewed-search-container'; const searchInput = document.createElement('input'); searchInput.type = 'search'; searchInput.id = 'last-viewed-search'; searchInput.placeholder = 'חיפוש בנצפו לאחרונה...'; searchInput.className = 'form-control'; searchContainer.appendChild(searchInput); popup.appendChild(searchContainer); const title = document.createElement('h2'); title.textContent = 'שרשורים שנצפו לאחרונה'; popup.appendChild(title); if (items.length === 0) { const emptyMsg = document.createElement('p'); emptyMsg.textContent = 'לא נצפו שרשורים לאחרונה.'; popup.appendChild(emptyMsg); } else { const list = document.createElement('ul'); list.id = 'last-viewed-list'; for (let i = 0; i < items.length; i++) { const item = items[i]; const listItem = document.createElement('li'); const link = document.createElement('a'); link.href = item.url; link.textContent = item.title || 'ללא כותרת'; link.target = '_blank'; listItem.appendChild(link); list.appendChild(listItem); } popup.appendChild(list); const noResultsMsg = document.createElement('p'); noResultsMsg.id = 'last-viewed-no-results'; noResultsMsg.textContent = 'לא נמצאו שרשורים תואמים.'; popup.appendChild(noResultsMsg); } const controlsDiv = document.createElement('div'); controlsDiv.className = 'popup-controls'; const clearButton = document.createElement('button'); clearButton.textContent = 'נקה היסטוריה'; clearButton.id = 'clear-last-viewed'; controlsDiv.appendChild(clearButton); const closeButton = document.createElement('button'); closeButton.textContent = 'סגור'; closeButton.className = 'close-popup-btn'; controlsDiv.appendChild(closeButton); popup.appendChild(controlsDiv); document.body.appendChild(popup); $('#clear-last-viewed').on('click', function(e) { e.stopPropagation(); if (confirm('האם אתה בטוח שברצונך למחוק את היסטוריית הצפייה?')) { GM_deleteValue(STORAGE_KEY); closePopupAndRemoveListener(); console.log("[LastViewed] History cleared."); } }); $('.close-popup-btn').on('click', function(e) { e.stopPropagation(); closePopupAndRemoveListener(); }); $('#last-viewed-search').on('input', filterLastViewedList); setTimeout(addClosePopupListener, 50); $('#last-viewed-search').trigger('focus'); } let currentTooltip = null; const TOOLTIP_TEXT = "נצפו לאחרונה"; const TOOLTIP_GAP = -88.5; function showDynamicTooltip(targetElement) { const sidebar = document.querySelector('nav[component="sidebar/left"]'); if (sidebar && sidebar.classList.contains('open')) { return; } removeDynamicTooltip(); currentTooltip = document.createElement('div'); currentTooltip.id = 'last-viewed-dynamic-tooltip'; currentTooltip.textContent = TOOLTIP_TEXT; document.body.appendChild(currentTooltip); const rect = targetElement.getBoundingClientRect(); const tooltipRect = currentTooltip.getBoundingClientRect(); let top = rect.top + (rect.height / 2) - (tooltipRect.height / 2); let left = rect.left + rect.width + TOOLTIP_GAP - 58; if (top < 5) top = 5; if (top + tooltipRect.height > window.innerHeight - 5) top = window.innerHeight - tooltipRect.height - 5; if (left + tooltipRect.width > window.innerWidth - 5) left = window.innerWidth - tooltipRect.width - 5; currentTooltip.style.top = `${top}px`; currentTooltip.style.left = `${left}px`; currentTooltip.style.right = 'auto'; } function removeDynamicTooltip() { if (currentTooltip) { currentTooltip.remove(); currentTooltip = null; } } function createSidebarButton() { console.log("[LastViewed] Attempting createSidebarButton execution..."); if ($('#last-viewed-btn-li').length > 0) { console.log("[LastViewed] Button LI already exists."); return; } console.log("[LastViewed] Selecting navList..."); const $navList = $('nav[component="sidebar/left"] ul#main-nav'); console.log(`[LastViewed] $navList length: ${$navList.length}`); if ($navList.length === 0) { console.error("[LastViewed] FAILED to find $navList."); return; } // Exit if navList not found console.log("[LastViewed] Selecting recentPostsItem..."); const $recentPostsItem = $navList.find('li a[href="/recent"]').closest('li'); console.log(`[LastViewed] $recentPostsItem length: ${$recentPostsItem.length}`); if ($recentPostsItem.length === 0) { console.error("[LastViewed] FAILED to find $recentPostsItem."); return; } // Exit if recent post item not found console.log("[LastViewed] Creating $newItem element..."); const $newItem = $(` <li class="nav-item mx-2" id="last-viewed-btn-li" data-bs-original-title="נצפו לאחרונה"> <a class="nav-link navigation-link d-flex gap-2 justify-content-between align-items-center" href="#" role="button" id="last-viewed-btn" aria-label="נצפו לאחרונה"> <span class="d-flex gap-2 align-items-center text-nowrap truncate-open"> <span class="position-relative"> <i class="fa fa-fw fa-history" data-content=""></i> <span component="navigation/count" class="visible-closed position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary hidden"></span> </span> <span class="nav-text small visible-open fw-semibold text-truncate">נצפו לאחרונה</span> </span> <span component="navigation/count" class="visible-open badge rounded-1 bg-primary hidden"></span> </a> </li> `); console.log("[LastViewed] Attaching listeners to $newItem..."); $newItem.find('a#last-viewed-btn').on('click', function(event) { event.preventDefault(); event.stopPropagation(); removeDynamicTooltip(); showLastViewedPopup(); }); $newItem.on('mouseenter', function(event) { showDynamicTooltip(event.currentTarget); }).on('mouseleave', function() { removeDynamicTooltip(); }); try { console.log("[LastViewed] Attempting insertBefore..."); $newItem.insertBefore($('li[data-bs-original-title="נושאים שלא נפתרו"]')); setTimeout(() => { if ($('#last-viewed-btn-li').length > 0) { console.log("[LastViewed] Button inserted successfully (verified)."); } else { console.error("[LastViewed] Button insertion failed silently (not found after insertBefore)."); } }, 50); } catch (e) { console.error("[LastViewed] Error during button insertion:", e); } } let observer = null; function setupMutationObserver() { const targetNode = document.getElementById('content'); if (!targetNode) { console.error("[LastViewed] Cannot find target node '#content'. Retrying..."); setTimeout(setupMutationObserver, 1000); return; } const config = { childList: true, subtree: true }; const callback = function(mutationsList, observer) { let titleSpanFound = false; for(const mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { if ($(node).find('span[component="topic/title"]').length > 0 || $(node).is('span[component="topic/title"]')) { titleSpanFound = true; } } }); } if (titleSpanFound) break; } if (titleSpanFound) { saveCurrentTopicDebounced(); } }; observer = new MutationObserver(callback); observer.observe(targetNode, config); const parentObserver = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.removedNodes.forEach(removedNode => { if (removedNode.id === 'content') { console.warn("[LastViewed] Target node #content was removed. Re-initializing observer."); if(observer) observer.disconnect(); setTimeout(setupMutationObserver, 50); } }); }); }); if (targetNode.parentNode) { parentObserver.observe(targetNode.parentNode, { childList: true }); } } function initialize() { console.log("[LastViewed] Initializing script v2.0.1 (Increased Timeout)..."); if (typeof createSidebarButton !== 'function' || typeof saveCurrentTopicDebounced !== 'function' || typeof setupMutationObserver !== 'function') { console.error("[LastViewed] CRITICAL: One or more core functions not defined!"); return; } console.log("[LastViewed] Calling createSidebarButton..."); createSidebarButton(); console.log("[LastViewed] Calling saveCurrentTopicDebounced (initial)..."); saveCurrentTopicDebounced(); console.log("[LastViewed] Calling setupMutationObserver..."); setupMutationObserver(); console.log("[LastViewed] Initialization complete."); } ensureDependencies(initialize); })();
בהנאה!
וכאן המקום להודות ל @עדלאידע שבהשראת הסקריפט שלו יצרתי את הסקריפט הזה.
עריכה: ותודה על השיפורים הנפלאים בסקריפט!לכל אלו שהמתינו וייחלו לדבר הזה, הנה זה הגיע! @ארץ-הצבי @חטח @יוסף-אלחנן
נ.ב. אשמח אם מישהו שמבין יוכל לפתח את זה ולפתוח pull request בgithub ל nodebb.
(באותו רעיון שכתבתי כאן...) -
הצעת ייעול | אתר מוזיקה חרדי למהדרין - אשמח לעזרתכם@היכל-הנגינה וואו! אתר מדהים!
קודם כל, יש להגדיר שהאתר הוא בעברית ולא באנגלית, כי אם כן, גוגל מתרגם אותו לעברית, והתוצאה היא - מקלת מלכות, או יותר גרוע - בערי אינטרנט...
כמו"כ נראה לי כי יועיל אם תהיה גם אפליקציה לאתר. (אולי יש... עוד לא חפרתי שם מספיק...)
תמשיכו הלאה להביא לנו דברים טובים... -
הצעת ייעול | עריכה ללא התראהבהקשר לכאן
קורה הרבה פעמים שמשתמשים עורכים משהו קטן בפוסט כגון שגיאת כתיב וכדו' ואז כל העוקבים מקבלים התראה על לא דבר. ע"כ חשבתי כי יועיל מאוד אם יעשו אפשרות שליחה ללא התראה לשאר המשתמשים כך כשמאן דהו עורך את ההודעה שלו, יוכל לעשות זאת בלי לשלוח התראה לכולם.
ו... כמובן, איך אפשר לסיים בלי להודות למנהלי הפורום הנכבדים...בכוונה לא תייגתי, שלא תגידו שאני סתם שולח התראות...
-
הצעת ייעול | תיבת ספאם בפורוםהיות שלאחרונה אני נתקל יותר ויותר בהודעות/תגובות שבמילה היפה הייתי מכנה אותן 'ספאם' חשבתי כי יהיה נכון לעשות מנגנון תיבת ספאם אוטומטית בפורום. וכך זה יעבוד;
1. תיבת ספאם גלובלית – כל פוסט שמסומן כספאם ע"י מספר מסוים של משתמשים יועבר אוטומטית לתיבת ספאם גלובלית.
2. מערכת התראות והגבלות למשתמשים שכותבים תוכן ספאמי:
- אזהרה ראשונה – משתמש שפרסם מספר פוסטים שסומנו כספאם יקבל הודעת אזהרה.
- הגבלת פרסום זמנית – אם דפוס הפעילות הספאמית ממשיך, פרסום המשתמש יוגבל לתקופה מסוימת (למשל שבוע).
- סינון אוטומטי של משתמשים בעייתיים – משתמש שמגיע לכמות מסוימת של פוסטים ספאמיים יועבר אוטומטית למצב שבו כל הודעותיו נשלחות לתיבת הספאם עד להחלטת מנהלים.
- סקירה מנהלית – מנהלי הפורום יוכלו לבדוק לאחר זמן האם להחזיר את המשתמש לפעילות רגילה או להשאיר אותו מסומן כספאם.
- מנגנון לערעור – משתמש שסבור שהפוסטים שלו סומנו כספאם שלא בצדק יוכל להגיש בקשה לבדיקה מחדש.
לגבי נקיטת הצעדים נגד המשתמשים עצמם עדיין מסופקני אם נכון יהיה לעשות את זה, אשמח לשמוע את דעתכם. וכמו"כ השאלה גם האם הודעת ספאם לא תופיע כלל, או שתופיע הודעה ריקה כמו בהודעה שנמחקה, רק במקום 'פוסט זה נמחק' יופיע 'ספאם' עם אפשרות לצפייה בהודעה?
כמו"כ לאלו שוודאי ישאלו, לא ניתן גם להרחיק לחלוטין את המשתמשים האלו בגין הודעות/תגובות אלו, כי אלו לא הודעות העוברות על חוקי הפורום, וגם לא עונות בהגדרתן על סעיף 2 בחוקי הפורום. וכנ"ל.אמנם כרגע קיימת אפשרות לדווח על הודעה/משתמש מסוים כספאם אבל בפועל ההודעה לא נשלחת לתיבת ספאם כלשהי אלא כנראה צוות פיקוח מוחק אותה ידנית אאל"ט.
וכעת לעניינינו: אני מודע לעובדה שלכאו' פיתוח דבר כזה תלוי בנודביבי ולא במנהלי הפורום היקרים, (אא"כ זה אחרת, אשמח לשמוע ולדעת) ע"כ כבר כתבתי זאת בפורום נודביבי ואשמח מאוד אם תוסיפו את המלצותיכם בשרשור ההוא שם ותצביעו בעדו.
https://community.nodebb.org/post/104495
כמו"כ אם יש לכם הערות והארות על הנושא אשמח לשמוע. -
הצעת ייעול | הוספת אפשרות תגובה עם אימוג'יאשמח אם המנהלים יוסיפו כאן בפורום אפשרות להגיב עם אימוג'י בתוך התגובה. כפי שיש בצ'אט.
זה ימנע לדעתי הרבה תגובות מיותרות כמו 'תודה' ו'כל הכבוד' וכדו' שמספימות וממלאות את השרשורים בתגובות מיותרות.ראיתי שהוסיפו את זה בהמוזיקאי אז אמרתי בטח אפשר לשים את זה גם פה.
-
שיתוף | צ'אטבוטים מסוננים לפי מקצוע או לפי רשימה שחורה | רובוליסט - רובוט חברותי חרדי!תראו מה זה, מגיד מישרים שמרביץ מוסר קם לנו פה:
ספר לי בדיחה טובה על המצב הבטחוני בארץ.
ChatGPT אמר:המצב הבטחוני הוא נושא רציני מאוד, במקום להתבדח עליו, עדיף להתפלל ולבקש מהקב"ה שישמור עלינו ויביא שלום ובטחון לעם
יש הרבה דרכים למצוא שמחה, ובמקום בדיחות על נושאים כואבים, אפשר למצוא סיפורים יפים על גדולי ישראל או חיזוקים
שתמיד נשמע בשורות טובות
אז אולי תספר לי סתם בדיחה טובה ברוח של 'אלול'?
ChatGPT אמר:
בשמחה! הנה בדיחה שמתאימה לרוח חודש אל
יום אחד פגש את חברו באמצע הרחוב ושואל אותו: "נו, מה נשמע? איך עובר עליך אלול?"
החבר עונה לו: "אל תשאל, אלול הזה אני ממש מרגיש כמו שופר!"
החבר מופתע ושואל: "כמו שופר? איך זה?"
החבר מחייך ועונה: "כן, כל הזמן מסתובב ומרגיש חלול מבפנים, ורק מחכה שמישהו שירים אותי כדי שאתחיל לצעוק!"
שנזכה לנצל את הזמן הזה להתקרבות לה'
שנשמע ונתבשר בשורות טובות!
-
המלצה | ועדת הרבנים יצאה עם פתרון חדש לקבלת קוד SMS לחשבון גימייל שננעל גם במספר כשר@איך כתב בהמלצה | ועדת הרבנים יצאה עם פתרון חדש לקבלת קוד SMS לחשבון גימייל שננעל גם במספר כשר:
אבל אי מתן אפשרות לשימוש במצלמה, או מסך מגע ושאר הצ'יפים, לדעתי זה רק הורס, יש הרבה שרק בשביל זה קונים תומך כשר, בזמן שאין במצלמה שום בעיה אמתית, אין למצלמה שום קשר עם אינטרנט.
מה שנכון נכון. אבל הבנתי מפי גורם שקשור לעניין, שהשקפת הוועדה היא - כל זמן שזה לא דבר שחייבים הם לא יכניסו סתם דברים מיותרים למכשיר. ואותו סיפור גם בנגן - עד שנגן לא הפך למוצר בסיס שהוא חובה, לא אישרו בוועדה נגן בפלא'. כיום שהמצב נהיה שכל אחד מסתובב עם נגן בכיס אחד ופלא' בכיס שני, אישרו בוועדה סו"ס להכניס נגן לפלאפון.
אז אולי הגיע הזמן שכולנו נתחיל להסתובב עם מצלמות בכיסים... -
הצעת ייעול | קמפיין מתמחים טופ לשרת חזקחבר'ה עכשיו תגובה רצינית. יש פה באג שכשאני פותח ספוילר אחד נפתח גם הספוילר של ההודעה הבאה.
-
להורדה | חדש! תוסף לאימוג'ים אישיים!שלום לכולם
בעקבות הלהיט החדש של האימוג'ים החרדיים בפרוג והביקוש העצום לכך, בס"ד פיתחתי (בעזרת AI כמובן...) תוסף כרום שמאפשר הדבקת אימוג'ים אישיים בכל מקום. התוסף לא מטמיע את האימוג'ים כמו אימוג'י אמיתי עם unicode, אלא הוא בסה"כ מצייר מחדש את התמונה שהעתקתם בגודל הרצוי ומדביקים אותה עם ctr+v.
ניתן גם לבצע הסרת רקע מהתמונה באמצעות הזנת מפתח API בתוסף (יש הוראות מפורטות בתוסף), ועוד אפשרויות רבות ומגוונות. התקינו ותהנו!
לתשומת לב! תוכן התוסף לא מסונכרן בין כל חשבונות גוגל במכשירים שונים. התמונות אותם אתם מעלים לתוסף קיימים רק במכשיר ההוא.
להורדה/התקנה
בקישור הנ"ל יש גם קובץ zip של האימוג'ים החרדיים להורדה וייבוא לתוסף.
בהצלחה. -
הצעת ייעול | עיצוב הפורוםהפוסטים בפורום 'גבוהים' מידי ויש הרבה חלל ריק בתוך כל פוסט, מה שמקשה על קריאה רציפה של אשכול, ובפרט ארוך. תועלת רבה תהיה אם יקטינו ויסירו את המרווחים האלו.
ובכללי - יועיל מאוד אם תהיה אפשרות לעיצוב אישי של הפורום, הכולל; קביעת גודל הפוסטים, גודל סוג וצבע הפונט, וכו'. -
סקריפט לניווט, קיפול והרחבת קטעי קוד ב-ChatGPT ו-AI Studioבתור אחד שעובד די הרבה עם בכתיבת קוד עם הבינה מלאכותית (כלומר, היא כותבת בשבילי...) עצבן אותי מאוד כל פעם שהייתי מקבל קטע קוד ארוך הייתי צריך לגלול את כולו כדי להגיע לסוף. אז בס"ד פניתי (איך לא?
) לעזרת הבינה והיא יצרה לי סקריפט לטמפרמונקי שמוסיף כפתורי קיפול והרחבת בלוקי הקוד וגם אפשרות גלילה לסוף/תחילת הקוד. (יצוין, שהבעיה קיימת רק ב-ChatGPT ו-AI Studio שכן בגרוק כבר קיימים כפתורים כאלו ובקלוד הקוד נפתח בקנבס צדדי כך שזה מיותר.)
אז מה יש לנו?
-
כפתורים שימושיים לכל בלוק קוד:
- מעל כל קטע קוד יופיעו שני כפתורים:
- כפתור "קפל": לחיצה עליו תעלים את הקוד (כדי לחסוך מקום במסך), ולחיצה נוספת תחזיר אותו ותשנה את הכפתור ל"הרחב".
- כפתור חץ למטה (↓): לחיצה עליו תקפיץ אתכם ישר לסוף של אותו קטע קוד.
- מתחת לכל קטע קוד יופיע כפתור נוסף:
- כפתור חץ למעלה (↑): לחיצה עליו תקפיץ אתכם חזרה להתחלה של אותו קטע קוד.
- מעל כל קטע קוד יופיעו שני כפתורים:
-
קיצורי דרך במקלדת (עם Ctrl):
- נמאס לכם להשתמש בעכבר לכל דבר? סתם שתדעו אפשר גם עם המקלדת...
Ctrl
+ חץ ימינה אוCtrl
+ חץ שמאלה: יקפל או ירחיב את בלוק הקוד שהכי קרוב למרכז המסך שלכם, או את האחרון שקיפלתם/הרחבתם.Ctrl
+ חץ למטה:- אם אתם בתחילת בלוק קוד, זה יקפיץ אתכם לסוף שלו.
- אם אתם כבר בסוף בלוק, זה יקפיץ אתכם לסוף של הבלוק הבא אחריו (אם יש).
Ctrl
+ חץ למעלה:- אם אתם בסוף בלוק קוד, זה יקפיץ אתכם להתחלה שלו.
- אם אתם כבר בהתחלה של בלוק, זה יקפיץ אתכם להתחלה של הבלוק הקודם (אם יש).
- נמאס לכם להשתמש בעכבר לכל דבר? סתם שתדעו אפשר גם עם המקלדת...
-
עובד גם כשנוסף קוד חדש:
- הסקריפט חכם מספיק כדי לזהות מתי ChatGPT או AI Studio מוסיפים קטעי קוד חדשים לשיחה, והוא ידאג להוסיף את הכפתורים והיכולות האלה גם אליהם באופן אוטומטי.
בשורה התחתונה:
הסקריפט הזה פשוט מוסיף כמה כפתורים קטנים ונוחים כדי להתמודד טוב יותר עם קטעי קוד ארוכים, לקפל אותם כשצריך, ולנווט ביניהם במהירות עם העכבר או המקלדת. לא מבין איך הסתדרתי בלעדיו עד היום...// ==UserScript== // @name Collapsible Code Blocks with RTL, Dynamic Tooltips & Keyboard Shortcuts // @namespace http://tampermonkey.net/ // @version 1.9.6 // @description Adds RTL code tools with smart tooltips, keyboard shortcuts (Ctrl+Arrows for navigation/toggle), styled UI and scroll features for ChatGPT and AI Studio. Further refined navigation with multiple collapsed blocks. // @author לאצי&AI // @match https://chatgpt.com/* // @match https://aistudio.google.com/* // @grant none // @icon https://img.icons8.com/ios-filled/50/programming.png // ==/UserScript== (function () { 'use strict'; // ... (CSS and functions: enhanceCodeBlocks, getAllEnhancedBlocksInDOM, findClosestBlock, updateNavigationStateIfNeeded - remain the same as 1.9.4 / 1.9.5) ... const style = document.createElement('style'); style.textContent = ` .code-toolbar-top, .code-toolbar-bottom { display: flex; gap: 6px; justify-content: flex-start; direction: rtl; text-align: right; margin: 6px 0; } .code-btn { background-color: #444; color: #fff; border: none; padding: 4px 8px; font-size: 12px; border-radius: 5px; cursor: pointer; transition: background-color 0.2s ease; position: relative; } .code-btn:hover { background-color: #666; } .code-btn::after { content: attr(data-tooltip); position: absolute; bottom: 100%; right: 0; background-color: #222; color: #fff; padding: 4px 6px; border-radius: 4px; white-space: nowrap; font-size: 11px; opacity: 0; pointer-events: none; transition: opacity 0.2s ease; margin-bottom: 6px; z-index: 9999; text-align: right; } .tooltip-below::after { bottom: auto; top: 100%; margin-bottom: 0; margin-top: 6px; } .code-btn:hover::after { opacity: 1; } `; document.head.appendChild(style); const enhancedBlockRegistry = []; let currentNavigationState = { blockInfo: null, targetPoint: 'top' }; let lastInteractedBlockForToggle = null; let lastManuallyCollapsedBlock = null; function enhanceCodeBlocks() { const blocks = document.querySelectorAll('pre'); blocks.forEach((block) => { if (block.dataset.enhanced) return; const toggleBtn = document.createElement('button'); toggleBtn.textContent = 'קפל'; toggleBtn.className = 'code-btn tooltip-below'; toggleBtn.setAttribute('data-tooltip', 'הצג או הסתר את בלוק הקוד'); const toBottomBtn = document.createElement('button'); toBottomBtn.textContent = '↓'; toBottomBtn.className = 'code-btn tooltip-below'; toBottomBtn.setAttribute('data-tooltip', 'גלול לסוף בלוק הקוד'); const toTopBtn = document.createElement('button'); toTopBtn.textContent = '↑'; toTopBtn.className = 'code-btn'; toTopBtn.setAttribute('data-tooltip', 'גלול לתחילת בלוק הקוד'); const toolbarTop = document.createElement('div'); toolbarTop.className = 'code-toolbar-top'; toolbarTop.appendChild(toggleBtn); toolbarTop.appendChild(toBottomBtn); const toolbarBottom = document.createElement('div'); toolbarBottom.className = 'code-toolbar-bottom'; toolbarBottom.appendChild(toTopBtn); const blockInfo = { preElement: block, toolbarTopElement: toolbarTop, toolbarBottomElement: toolbarBottom, toggleButtonElement: toggleBtn, id: `enhanced-block-${enhancedBlockRegistry.length}` }; toggleBtn.addEventListener('click', () => { const visible = block.style.display !== 'none'; block.style.display = visible ? 'none' : 'block'; toggleBtn.textContent = visible ? 'הרחב' : 'קפל'; if (!visible) { // Block was just expanded if (lastManuallyCollapsedBlock && lastManuallyCollapsedBlock.id === blockInfo.id) { lastManuallyCollapsedBlock = null; } } // Note: lastManuallyCollapsedBlock is primarily set via keydown for intent. }); toBottomBtn.addEventListener('click', () => { toolbarBottom.scrollIntoView({ behavior: 'smooth', block: 'center' }); }); toTopBtn.addEventListener('click', () => { toolbarTop.scrollIntoView({ behavior: 'smooth', block: 'center' }); }); if (block.parentNode) { block.parentNode.insertBefore(toolbarTop, block); block.parentNode.insertBefore(toolbarBottom, block.nextSibling); } enhancedBlockRegistry.push(blockInfo); block.dataset.enhanced = "true"; block.dataset.blockId = blockInfo.id; }); } function getAllEnhancedBlocksInDOM() { // Ensure this list is always up-to-date with the DOM order // This might need re-evaluation if blocks can be reordered in the DOM by other means const livePreElements = Array.from(document.querySelectorAll('pre[data-enhanced="true"]')); return livePreElements.map(pre => { const foundInfo = enhancedBlockRegistry.find(info => info.id === pre.dataset.blockId); return foundInfo; // Should always find it if registry is in sync }).filter(Boolean); // Filter out any undefined if a pre was removed weirdly } function findClosestBlock(blocksToSearch, includeCollapsed = false) { if (!blocksToSearch || blocksToSearch.length === 0) return null; let closestBlockInfo = null; let minDistance = Infinity; const viewportCenterY = window.innerHeight / 2; blocksToSearch.forEach(blockInfo => { if(!blockInfo) return; // Safety check const preElement = blockInfo.preElement; if (!includeCollapsed && preElement.style.display === 'none') return; const elementForLocation = preElement.style.display === 'none' ? blockInfo.toolbarTopElement : preElement; if (!elementForLocation || !document.body.contains(elementForLocation)) return; const rect = elementForLocation.getBoundingClientRect(); if (rect.bottom > 0 && rect.top < window.innerHeight) { const elementCenterY = rect.top + rect.height / 2; const distance = Math.abs(elementCenterY - viewportCenterY); if (distance < minDistance) { minDistance = distance; closestBlockInfo = blockInfo; } } }); return closestBlockInfo; } function updateNavigationStateIfNeeded(purpose = 'navigation') { const allDomBlocks = getAllEnhancedBlocksInDOM(); // This now reflects current DOM order if (allDomBlocks.length === 0) { currentNavigationState.blockInfo = null; if (lastInteractedBlockForToggle && !document.body.contains(lastInteractedBlockForToggle.preElement)) lastInteractedBlockForToggle = null; if (lastManuallyCollapsedBlock && !document.body.contains(lastManuallyCollapsedBlock.preElement)) lastManuallyCollapsedBlock = null; return { allBlocks: [], visibleBlocks: [] }; } let blockToFocus = null; let visibleBlocks = allDomBlocks.filter(b => b.preElement.style.display !== 'none'); if (purpose === 'toggle') { if (lastInteractedBlockForToggle && document.body.contains(lastInteractedBlockForToggle.preElement)) { blockToFocus = allDomBlocks.find(b => b.id === lastInteractedBlockForToggle.id); } if (!blockToFocus) { blockToFocus = findClosestBlock(allDomBlocks, true); } } else { let currentNavBlockId = currentNavigationState.blockInfo?.id; const currentBlockFromAll = currentNavBlockId ? allDomBlocks.find(b => b.id === currentNavBlockId) : null; if (currentBlockFromAll && currentBlockFromAll.preElement.style.display !== 'none') { blockToFocus = currentBlockFromAll; } else if (lastManuallyCollapsedBlock && document.body.contains(lastManuallyCollapsedBlock.preElement) && lastManuallyCollapsedBlock.preElement.style.display === 'none' && currentBlockFromAll && currentBlockFromAll.id === lastManuallyCollapsedBlock.id) { blockToFocus = currentBlockFromAll; } else { blockToFocus = findClosestBlock(visibleBlocks, false); } if (!blockToFocus && visibleBlocks.length > 0) { blockToFocus = visibleBlocks[0]; } else if (!blockToFocus && lastManuallyCollapsedBlock && lastManuallyCollapsedBlock.preElement.style.display === 'none') { blockToFocus = allDomBlocks.find(b => b.id === lastManuallyCollapsedBlock.id); } if (blockToFocus && blockToFocus.preElement.style.display !== 'none' && (!currentNavigationState.blockInfo || blockToFocus.id !== currentNavigationState.blockInfo.id) ) { const rect = blockToFocus.preElement.getBoundingClientRect(); currentNavigationState.targetPoint = (rect.height > 0 && Math.abs(rect.top - window.innerHeight / 2) < Math.abs(rect.bottom - window.innerHeight / 2)) ? 'top' : 'bottom'; } else if (!blockToFocus) { currentNavigationState.blockInfo = null; } } currentNavigationState.blockInfo = blockToFocus; return { allBlocks: allDomBlocks, visibleBlocks: visibleBlocks }; } document.addEventListener('keydown', function (event) { if (!event.ctrlKey) return; const { allBlocks, visibleBlocks } = updateNavigationStateIfNeeded(event.key === 'ArrowLeft' || event.key === 'ArrowRight' ? 'toggle' : 'navigation'); let currentBlockForNav = currentNavigationState.blockInfo; switch (event.key) { case 'ArrowLeft': case 'ArrowRight': event.preventDefault(); if (currentBlockForNav) { currentBlockForNav.toggleButtonElement.click(); lastInteractedBlockForToggle = currentBlockForNav; if (currentBlockForNav.preElement.style.display === 'none') { lastManuallyCollapsedBlock = currentBlockForNav; } else { if (lastManuallyCollapsedBlock && lastManuallyCollapsedBlock.id === currentBlockForNav.id) { lastManuallyCollapsedBlock = null; } } } break; case 'ArrowDown': event.preventDefault(); if (!currentBlockForNav) { currentBlockForNav = visibleBlocks.length > 0 ? visibleBlocks[0] : (lastManuallyCollapsedBlock && lastManuallyCollapsedBlock.preElement.style.display === 'none' ? allBlocks.find(b => b.id === lastManuallyCollapsedBlock.id) : null); if (!currentBlockForNav) break; currentNavigationState.blockInfo = currentBlockForNav; currentNavigationState.targetPoint = (currentBlockForNav.preElement.style.display === 'none') ? 'top' : 'top'; } if (currentBlockForNav.preElement.style.display !== 'none' && currentNavigationState.targetPoint === 'top') { currentBlockForNav.toolbarBottomElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); currentNavigationState.targetPoint = 'bottom'; } else { const currentBlockIndexInFullList = allBlocks.findIndex(b => b.id === currentBlockForNav.id); let nextTargetBlock = null; for (let i = currentBlockIndexInFullList + 1; i < allBlocks.length; i++) { const potentialTarget = allBlocks[i]; if (lastManuallyCollapsedBlock && potentialTarget.id === lastManuallyCollapsedBlock.id && potentialTarget.preElement.style.display === 'none') { nextTargetBlock = potentialTarget; break; } if (potentialTarget.preElement.style.display !== 'none') { nextTargetBlock = potentialTarget; break; } } if (nextTargetBlock) { currentNavigationState.blockInfo = nextTargetBlock; const targetElementForScroll = nextTargetBlock.preElement.style.display === 'none' ? nextTargetBlock.toolbarTopElement : nextTargetBlock.toolbarBottomElement; const scrollTargetPoint = nextTargetBlock.preElement.style.display === 'none' ? 'top' : 'bottom'; targetElementForScroll.scrollIntoView({ behavior: 'smooth', block: 'center' }); currentNavigationState.targetPoint = scrollTargetPoint; if (nextTargetBlock.preElement.style.display === 'none') { lastInteractedBlockForToggle = nextTargetBlock; } else { lastInteractedBlockForToggle = null; } } } break; case 'ArrowUp': event.preventDefault(); if (!currentBlockForNav) { currentBlockForNav = visibleBlocks.length > 0 ? visibleBlocks[visibleBlocks.length - 1] : (lastManuallyCollapsedBlock && lastManuallyCollapsedBlock.preElement.style.display === 'none' ? allBlocks.find(b => b.id === lastManuallyCollapsedBlock.id) : null); if (!currentBlockForNav) break; currentNavigationState.blockInfo = currentBlockForNav; currentNavigationState.targetPoint = (currentBlockForNav.preElement.style.display === 'none') ? 'bottom' : 'bottom'; } if (currentBlockForNav.preElement.style.display !== 'none' && currentNavigationState.targetPoint === 'bottom') { currentBlockForNav.toolbarTopElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); currentNavigationState.targetPoint = 'top'; } else { const currentBlockIndexInFullList = allBlocks.findIndex(b => b.id === currentBlockForNav.id); let prevTargetBlock = null; for (let i = currentBlockIndexInFullList - 1; i >= 0; i--) { const potentialTarget = allBlocks[i]; if (lastManuallyCollapsedBlock && potentialTarget.id === lastManuallyCollapsedBlock.id && potentialTarget.preElement.style.display === 'none') { prevTargetBlock = potentialTarget; break; } if (potentialTarget.preElement.style.display !== 'none') { prevTargetBlock = potentialTarget; break; } } if (prevTargetBlock) { currentNavigationState.blockInfo = prevTargetBlock; prevTargetBlock.toolbarTopElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); currentNavigationState.targetPoint = 'top'; if (prevTargetBlock.preElement.style.display === 'none') { lastInteractedBlockForToggle = prevTargetBlock; } else { lastInteractedBlockForToggle = null; } } } break; } }); const observer = new MutationObserver(() => { enhanceCodeBlocks(); // Potentially re-validate currentNavigationState if DOM changes significantly // For now, rely on keydown to re-evaluate. }); observer.observe(document.body, { childList: true, subtree: true }); enhanceCodeBlocks(); updateNavigationStateIfNeeded('navigation'); })();
קיים באג קטן בניווט בין קטעי הקוד באמצעות מקשי הקיצור, כשחלק מהבלוקים מקופלים הוא עלול לדלג עליהם.
כמו"כ אשמח אם מישהו יוכל לשפר את הקוד כך שהכפתורים יהיו דביקים ויופיעו כל הזמן לאורך כל הגלילה בבלוק הקוד הנוכחי, כך שיהיו זמינים כל הזמן. כמובן שבמקרה כזה כל הכפתורים צריכים להופיע בשורה אחת ולא בשני שורות נפרדות כמו עכשיו. -
-
שיתוף | ווידגט לזכרון חורבן בית המקדש לאנדרואיד@מתושלח-הבבלי כתב בשיתוף | ווידגט לזכרון חורבן בית המקדש לאנדרואיד:
אולי תוסיף ווידג'ט על החטופים?
אני יודע שכולם יגידו שזה לא מתאים וכו'
אבל בתכלס' למה שלא נזכור שיש לנו אחים שנמצאים בשבי חמאס ימ"ש?אם תרצו לעשות משהו באמת מועיל למען אחינו החטופים, אפשר לעשות ווידג'ט או אפליקציה עם תזכורת לפרק תהילים יומי לזכותם ורצוי אפי' לצרף רשימה של שמות החטופים לתפילה. וה' יעזור שעד שיפתחו כזה דבר, כל החטופים כבר יחזרו הביתה בשלום.
-
הצעת ייעול | קטגוריה לתרגום תוכנותעקב כך שראיתי פה הרבה בפורום שרוצים לתרגם תוכנות (כאן ואני הקטן... ובטח יש עוד הרבה ואטו כרוכלא...) ועקב כך שלא בכל תוכנה יש אפשרות לעברית (אמנם יש תוכנות חלופיות אך לא כל פעם זה רלוונטי ואכמ"ל) חשבתי על רעיון מועיל שיפתחו כאן קטגוריה של עזרה הדדית לתרגום תוכנות, שכל אחד שרוצה לתרגם תוכנה כלשהיא יעלה אותה לשם וכך תתחלק העבודה בין מתנדבים. (וכמו שראיתי שיש כאו חבר'ה שבאמת יודעים ת'עבודה עי' כאן וכאן.) ניתן אפי' לעשות טבלה ובה חלוקה מסודרת של הקבצים לתרגום וכל אחד מסמן מה הוא לקח. וכמובן בסיום התרגום כל אחד מעלה לשם את הקבצים המתורגמים, והרי לנו עבודה למופת.
-
שיתוף | הצעה לאפליקציה/תוכנה חמודה להצגת אחוזי הסוללהאחרי שראיתי את התמונה הזאת:
חשבתי כזה לעצמי - למה באמת לא לעשות מזה משהו אמיתי שעל יד אחוזי הסוללה יראו כזה אימוג'י חמוד...
נשמע לכם? מי לוקח על עצמו את הפרויקט לאנדרואיד/ווינדוס? (ניתן לקחת גם רק אחד מהם... אני מרשה...)
-
הצעת ייעול | חיפוש ושדרוג מערכת ל-AIיועיל מאוד אם יעשו פה חיפוש חכם מבוסס בינה מלאכותית כמו שג'ימייל השיקו עכשיו, שבמקום לחפש שעות איזו תוכנה או פוסט הבינה פשוט 'משוחחת' איתך ועוזרת לך להגיע במהירות למקום המבוקש.
סתם כך ניתן לעשות ב'עזרה הדדית' קטגוריה לשאלות לצ'אט gpt שיענה בקלות ובמהירות על השאלות. (כמובן צ'אט מסונן כפי הנדרש).עריכה: (נלקח מההמשך למטה)
מה שאני מציע לעשות זה בעצם שני דברים נפרדים.
1.חיפוש חכם שהבינה שואלת אותך מה אתה מחפש ואת זה היא מביאה לך רק מתוך הפורום עצמו.
2.צ'אט gpt שמבוסס מידע על כל הרשת אך הוא מביא מידע אך ורק על עניינים הקשורים לטכנולוגיה בלבד. מה שאנחנו מרויחים זה צ'אט מסונן ללא חומר מיותר (ואסור), וגם זה כמו עזרה הדדית חכמה שאפשר לשאול אותה גם על נושאים שעדיין לא נדונו בפורום. -
באג | לא מופיע ספויילר באמצע פוסט@סקרנות ברוכים הבאים לפורום מתמחים טופ.
להלן כמה כללים שיעזרו לך להתאקלם כראוי בסביבת הפורום:- נהוג שלא לתייג את המנהלים החשובים על כל דבר קטן.
- בכל ספוילר (בכל פורום שהוא) יש לשים רווח שורה לפני ושורה אחרי כדי שהספוילר יכנס לתוקפו. זה לא באג.
- נא סמן את השרשור הנוכחי כנפתר, זאת ע"י לחיצה על 'כלי הנושא' > 'סמן כשאלה'> ולאחמ"כ שוב > סמן כנפתר.
- מומלץ וחשוב לקרוא את המדריך של ידידינו @מתחיל-מומחה שהשקיע ועשה הסבר מפורט על אופן השימוש במערכת כאן.
- (אם לא יצא לך לעבור עד עכשיו על חוקי הפורום מומלץ וחשוב לעשות זאת.)
בהצלחה רבה והרבה סייעתא דשמיא!