From 7659792b55cef11ae274bfd192fc650004c1692a Mon Sep 17 00:00:00 2001 From: numex-admin Date: Wed, 9 Sep 2026 22:38:21 +0000 Subject: [PATCH] =?UTF-8?q?Numex=20yay=C4=B1n:=20public/js/app-terminal.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/app-terminal.js | 206 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 public/js/app-terminal.js diff --git a/public/js/app-terminal.js b/public/js/app-terminal.js new file mode 100644 index 0000000..53b94fb --- /dev/null +++ b/public/js/app-terminal.js @@ -0,0 +1,206 @@ +/* ============================================================ + AURA OS — Uygulama B: Hacker Terminali (CRT konsol) + Komutlar: help, date, notes, clear + ============================================================ */ + +const TermAppState = {}; + +function termEscape(s) { + return String(s).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + +function termWrite(outputEl, html, cls) { + if (!outputEl) return; + const div = document.createElement('div'); + if (cls) div.className = cls; + div.innerHTML = html; + outputEl.appendChild(div); + outputEl.scrollTop = outputEl.scrollHeight; +} + +function termWriteRawText(outputEl, text) { + if (!outputEl) return; + const div = document.createElement('div'); + div.textContent = text; + outputEl.appendChild(div); + outputEl.scrollTop = outputEl.scrollHeight; +} + +/* CRT açılış banner'ı */ +function termBanner(outputEl) { + termWrite(outputEl, ' ▄▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄ ▄ ▄▄▄▄▄'); + termWrite(outputEl, ' █ ▀ █▄ █ █▀▄▀ ▀▄▄ █ ▀▄▀▀▄▀ █▀▄▀▀'); + termWrite(outputEl, ''); + termWrite(outputEl, 'AURA OS • Hacker Terminali v1.0 • CRT-720p'); + termWrite(outputEl, 'Güvenli kanal kuruldu. Yardım için "help" yaz.'); + termWrite(outputEl, ''); +} + +/* Komut işleyici */ +async function termRunCommand(outputEl, rawCommand) { + const cmd = (rawCommand || '').trim(); + const lower = cmd.toLowerCase(); + + if (cmd === '') return; + + switch (lower) { + case 'help': + termWrite(outputEl, '━━ KULLANILABİLİR KOMUTLAR ━━'); + termHelp(outputEl); + break; + + case 'clear': + outputEl.innerHTML = ''; + termBanner(outputEl); + break; + + case 'date': + termWrite(outputEl, 'Sistem saati: ' + termEscape(new Date().toString()) + ''); + break; + + case 'notes': + await termNotes(outputEl); + break; + + default: + termWrite(outputEl, 'zsh: komut bulunamadı: ' + termEscape(cmd) + + ' ("help" ile komutlara bak)'); + } +} + +function termHelp(outputEl) { + const rows = [ + ['help', 'Kullanılabilir komutları listeler'], + ['date', 'Canlı sistem saatini yazar'], + ['notes', 'Backend API\'den alınan kayıtlı notları terminale döker'], + ['clear', 'Ekranı temizler ve başlığı yeniden basar'], + ['banner','Açılış banner\'ını yeniden gösterir'], + ['echo <metin>', 'Yazdığın metni geri basar'], + ]; + rows.forEach(r => { + termWrite(outputEl, + ' ' + termEscape(r[0]).padEnd(14, ' ') + '' + + '' + termEscape('— ' + r[1]) + ''); + }); + termWrite(outputEl, ''); +} + +async function termNotes(outputEl) { + try { + const res = await fetch('/api/notes', { method: 'GET' }); + if (!res.ok) throw new Error('HTTP ' + res.status); + const data = await res.json(); + const notes = data.notes || []; + + termWrite(outputEl, '▸ GET /api/notes — backend yanıtı alındı (' + notes.length + ' kayıt)'); + + if (notes.length === 0) { + termWrite(outputEl, 'Kayıtlı not bulunamadı. Not defteri uygulamasından not ekleyin.'); + termWrite(outputEl, ''); + return; + } + + notes.forEach((n, i) => { + const time = n.createdAt ? new Date(n.createdAt) : null; + let stamp = ''; + if (time) { + stamp = String(time.getDate()).padStart(2,'0') + '.' + + String(time.getMonth()+1).padStart(2,'0') + '.' + + time.getFullYear() + ' ' + + String(time.getHours()).padStart(2,'0') + ':' + + String(time.getMinutes()).padStart(2,'0'); + } + termWrite(outputEl, + '[' + String(i + 1) + '] ' + + '' + termEscape(n.text) + ''); + if (stamp) termWrite(outputEl, ' ▸ ' + stamp + ''); + }); + termWrite(outputEl, ''); + } catch (err) { + termWrite(outputEl, 'api' + 'nı çekerken hata: ' + termEscape(err.message) + ''); + } +} + +/* Term'de kullanılacak özel komutlar için echo desteği */ +async function termRunExtended(outputEl, cmd) { + const lower = cmd.toLowerCase(); + if (cmd.startsWith('echo ')) { + termWriteRawText(outputEl, cmd.slice(5)); + return true; + } + if (lower === 'banner') { + termBanner(outputEl); + return true; + } + if (lower === 'whoami') { + termWrite(outputEl, 'root@aura-os (yetkili operatör)'); + return true; + } + if (lower === 'clear') return false; // handled + return false; +} + +/* Uygulama başlatma */ +function termBuildContent() { + const tpl = document.getElementById('tpl-terminal'); + if (tpl && tpl.content) { + return document.importNode(tpl.content, true).firstElementChild.innerHTML; + } + return [ + '
', + '
', + '
root@aura:~$', + '
', + '
' + ].join(''); +} + +registerApp('terminal', { + name: 'Hacker Terminali', + icon: '⌨️', + defaultWidth: 600, + defaultHeight: 420, + windowTitle: 'Hacker Terminali — Aura OS', + windowProps: { width: 600, height: 420 }, + + buildContent: termBuildContent, + + onLaunch(record, bodyEl) { + bodyEl.innerHTML = termBuildContent(); + + const outputEl = bodyEl.querySelector('.term-output'); + const inputEl = bodyEl.querySelector('.term-input'); + + if (!outputEl || !inputEl) return; + + // Banner göster + termBanner(outputEl); + + // Odak inputa + setTimeout(() => inputEl.focus(), 60); + + // Enter tuşu + inputEl.addEventListener('keydown', async (e) => { + if (e.key === 'Enter') { + const cmd = inputEl.value; + // komutu göster + termWrite(outputEl, 'root@aura:~$ ' + termEscape(cmd)); + + const extendedHandled = await termRunExtended(outputEl, cmd); + if (!extendedHandled) { + await termRunCommand(outputEl, cmd); + } + + inputEl.value = ''; + outputEl.scrollTop = outputEl.scrollHeight; + } + }); + + // Pencere odaklanınca inputa odaklan + record.el.addEventListener('mousedown', (ev) => { + if (!ev.target.closest('.term-input')) { + setTimeout(() => inputEl.focus(), 40); + } + }); + }, +});