MemoryLens V1sp

Tarayıcı geçmişini zeki bir hafızaya dönüştürür. (TR/EN Dil Destekli)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name          MemoryLens V1sp
// @namespace     http://tampermonkey.net/
// @version       1.3
// @description   Tarayıcı geçmişini zeki bir hafızaya dönüştürür. (TR/EN Dil Destekli)
// @author        Mustafa Hakan
// @match         *://*/*
// @grant         none
// ==/UserScript==

/* jshint esversion: 8 */

(function() {
    'use strict';

    // --- [1. EVRENSEL DİL MOTORU] ---
    const userLang = navigator.language.startsWith('tr') ? 'tr' : 'en';
    
    const TRANSLATIONS = {
        tr: {
            placeholder: "Hafızanda ara... (Alt+K)",
            noResult: "Sonuç bulunamadı.",
            untitled: "Başlıksız Sayfa"
        },
        en: {
            placeholder: "Search in memory... (Alt+K)",
            noResult: "No results found.",
            untitled: "Untitled Page"
        }
    };

    const UI_TEXT = TRANSLATIONS[userLang];

    // --- [2. VERİTABANI] ---
    var DB_NAME = "MemoryLensDB";
    var STORE_NAME = "pages";

    var initDB = function() {
        return new Promise(function(resolve) {
            var request = indexedDB.open(DB_NAME, 1);
            request.onupgradeneeded = function(e) {
                var db = e.target.result;
                if (!db.objectStoreNames.contains(STORE_NAME)) {
                    var store = db.createObjectStore(STORE_NAME, { keyPath: "url" });
                    store.createIndex("title", "title", { unique: false });
                    store.createIndex("text", "text", { unique: false });
                }
            };
            request.onsuccess = function(e) { resolve(e.target.result); };
        });
    };

    var saveCurrentPage = async function() {
        try {
            var db = await initDB();
            var tx = db.transaction(STORE_NAME, "readwrite");
            var store = tx.objectStore(STORE_NAME);

            var pageData = {
                url: window.location.href,
                title: document.title,
                text: (document.body.innerText || "").slice(0, 3000).replace(/\s+/g, ' '),
                timestamp: Date.now(),
                domain: window.location.hostname
            };

            store.put(pageData);
        } catch (err) {
            console.warn("MemoryLens Save Error:", err);
        }
    };

    window.addEventListener('load', function() {
        setTimeout(saveCurrentPage, 2000);
    });

    // --- [3. ARAYÜZ] ---
    var createUI = function() {
        if (document.getElementById('ml-overlay')) return document.getElementById('ml-overlay');

        var overlay = document.createElement('div');
        overlay.id = 'ml-overlay';
        overlay.innerHTML = 
            '<div id="ml-modal">' +
                // DİL MOTORU BURADA DEVREYE GİRİYOR:
                '<input type="text" id="ml-search" placeholder="' + UI_TEXT.placeholder + '" autocomplete="off" />' +
                '<div id="ml-results"></div>' +
            '</div>' +
            '<style>' +
                '#ml-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.4); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); z-index: 999999; display: none; align-items: flex-start; justify-content: center; padding-top: 15vh; font-family: sans-serif; }' +
                '#ml-modal { background: #fff; width: 600px; border-radius: 12px; box-shadow: 0 20px 50px rgba(0,0,0,0.2); overflow: hidden; }' +
                '#ml-search { width: 100%; border: none; padding: 20px; font-size: 18px; outline: none; border-bottom: 1px solid #eee; background: #fff; color: #000; }' +
                '#ml-results { max-height: 400px; overflow-y: auto; background: #fff; }' +
                '.ml-item { padding: 15px 20px; border-bottom: 1px solid #f9f9f9; cursor: pointer; transition: 0.2s; color: #000; display: block; text-decoration: none; }' +
                '.ml-item:hover { background: #f5faff; }' +
                '.ml-title { font-weight: 600; color: #1a1a1a; margin-bottom: 4px; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }' +
                '.ml-meta { font-size: 12px; color: #888; }' +
            '</style>';
        
        document.body.appendChild(overlay);

        var searchInput = overlay.querySelector('#ml-search');
        searchInput.addEventListener('input', async function(e) {
            var query = e.target.value.toLowerCase();
            if (query.length < 2) {
                document.getElementById('ml-results').innerHTML = '';
                return;
            }

            var db = await initDB();
            var tx = db.transaction(STORE_NAME, "readonly");
            var store = tx.objectStore(STORE_NAME);
            var request = store.getAll();

            request.onsuccess = function() {
                var results = request.result
                    .filter(function(item) { 
                        return (item.title.toLowerCase().indexOf(query) !== -1 || 
                                item.text.toLowerCase().indexOf(query) !== -1 ||
                                item.url.toLowerCase().indexOf(query) !== -1);
                    })
                    .sort(function(a, b) { return b.timestamp - a.timestamp; })
                    .slice(0, 10);

                renderResults(results);
            };
        });

        return overlay;
    };

    var renderResults = function(results) {
        var resContainer = document.getElementById('ml-results');
        if (results.length === 0) {
            resContainer.innerHTML = '<div style="padding:20px; color:#999; text-align:center;">' + UI_TEXT.noResult + '</div>';
            return;
        }
        resContainer.innerHTML = results.map(function(item) {
            var dateStr = new Date(item.timestamp).toLocaleDateString();
            return '<div class="ml-item" data-url="' + item.url + '">' +
                '<span class="ml-title">' + (item.title || UI_TEXT.untitled) + '</span>' +
                '<span class="ml-meta">' + item.domain + ' • ' + dateStr + '</span>' +
            '</div>';
        }).join('');

        resContainer.querySelectorAll('.ml-item').forEach(function(el) {
            el.onclick = function() { window.location.href = this.getAttribute('data-url'); };
        });
    };

    // --- [4. TETİKLEYİCİLER] ---
    window.addEventListener('keydown', function(e) {
        if (e.altKey && e.key.toLowerCase() === 'k') {
            e.preventDefault();
            var overlay = createUI();
            var isVisible = overlay.style.display === 'flex';
            overlay.style.display = isVisible ? 'none' : 'flex';
            if (!isVisible) document.getElementById('ml-search').focus();
        }
        if (e.key === 'Escape') {
            var overlayEl = document.getElementById('ml-overlay');
            if (overlayEl) overlayEl.style.display = 'none';
        }
    });

})();