From cd84e4e04e8dcbaf09fb02f460c2a5e63d40b29f Mon Sep 17 00:00:00 2001 From: VexCode24 Date: Mon, 25 May 2026 07:33:47 -0400 Subject: [PATCH] Add GitHub chat content script --- github-chat.css | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ github-chat.js | 128 ++++++++++++++++++++++++++++++++++++++++++ manifest.json | 11 ++++ 3 files changed, 283 insertions(+) create mode 100644 github-chat.css create mode 100644 github-chat.js diff --git a/github-chat.css b/github-chat.css new file mode 100644 index 0000000..269ab48 --- /dev/null +++ b/github-chat.css @@ -0,0 +1,144 @@ +#github-stories-chat-root { + position: fixed; + right: 24px; + bottom: 24px; + z-index: 9999; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +.github-chat-toggle { + min-width: 56px; + height: 40px; + padding: 0 14px; + border: 1px solid #1f883d; + border-radius: 20px; + background: #1f883d; + color: #fff; + cursor: pointer; + font-weight: 600; + box-shadow: 0 8px 24px rgba(31, 35, 40, 0.18); +} + +.github-chat-panel { + position: absolute; + right: 0; + bottom: 52px; + width: min(360px, calc(100vw - 32px)); + height: min(520px, calc(100vh - 120px)); + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid #d0d7de; + border-radius: 8px; + background: #fff; + color: #1f2328; + box-shadow: 0 16px 48px rgba(31, 35, 40, 0.22); +} + +.github-chat-hidden { + display: none; +} + +.github-chat-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 12px; + padding: 12px 14px; + border-bottom: 1px solid #d0d7de; + background: #f6f8fa; +} + +.github-chat-context { + display: block; + max-width: 260px; + margin-top: 2px; + overflow: hidden; + color: #57606a; + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.github-chat-close { + width: 28px; + height: 28px; + border: 0; + border-radius: 6px; + background: transparent; + color: #57606a; + cursor: pointer; + font-size: 18px; + line-height: 1; +} + +.github-chat-close:hover, +.github-chat-close:focus { + background: #eaeef2; +} + +.github-chat-messages { + flex: 1; + overflow-y: auto; + padding: 14px; + background: #fff; +} + +.github-chat-empty { + margin: 0; + color: #57606a; + font-size: 13px; +} + +.github-chat-message { + margin-bottom: 12px; + padding: 10px 12px; + border: 1px solid #d8dee4; + border-radius: 8px; + background: #f6f8fa; +} + +.github-chat-message-meta { + margin-bottom: 4px; + color: #57606a; + font-size: 11px; +} + +.github-chat-message-body { + color: #1f2328; + font-size: 14px; + line-height: 1.4; + overflow-wrap: anywhere; + white-space: pre-wrap; +} + +.github-chat-form { + display: flex; + gap: 8px; + padding: 12px; + border-top: 1px solid #d0d7de; + background: #f6f8fa; +} + +.github-chat-input { + flex: 1; + min-width: 0; + resize: none; + border: 1px solid #d0d7de; + border-radius: 6px; + padding: 8px; + color: #1f2328; + font: inherit; +} + +.github-chat-send { + align-self: flex-end; + min-width: 64px; + height: 36px; + border: 1px solid #1f883d; + border-radius: 6px; + background: #1f883d; + color: #fff; + cursor: pointer; + font-weight: 600; +} diff --git a/github-chat.js b/github-chat.js new file mode 100644 index 0000000..51e94fb --- /dev/null +++ b/github-chat.js @@ -0,0 +1,128 @@ +initGithubChat(); + +function initGithubChat() { + if (window.location.hostname !== 'github.com') return; + if (document.getElementById('github-stories-chat-root')) return; + + const root = document.createElement('div'); + root.id = 'github-stories-chat-root'; + root.innerHTML = ` + +
+
+
+ GitHub Chat + +
+ +
+
+
+ + +
+
+ `; + + document.body.appendChild(root); + + const toggle = root.querySelector('.github-chat-toggle'); + const panel = root.querySelector('.github-chat-panel'); + const close = root.querySelector('.github-chat-close'); + const form = root.querySelector('.github-chat-form'); + const input = root.querySelector('.github-chat-input'); + const messages = root.querySelector('.github-chat-messages'); + const context = root.querySelector('.github-chat-context'); + const chatContext = getGithubChatContext(); + const storageKey = `github-stories-chat:${chatContext.key}`; + + context.innerText = chatContext.label; + + function renderMessages() { + const savedMessages = getSavedChatMessages(storageKey); + messages.innerHTML = ''; + + if (savedMessages.length === 0) { + const empty = document.createElement('p'); + empty.className = 'github-chat-empty'; + empty.innerText = 'No messages yet.'; + messages.appendChild(empty); + return; + } + + savedMessages.forEach((message) => { + const item = document.createElement('article'); + item.className = 'github-chat-message'; + + const meta = document.createElement('div'); + meta.className = 'github-chat-message-meta'; + meta.innerText = message.createdAt; + + const body = document.createElement('div'); + body.className = 'github-chat-message-body'; + body.innerText = message.text; + + item.appendChild(meta); + item.appendChild(body); + messages.appendChild(item); + }); + + messages.scrollTop = messages.scrollHeight; + } + + function setPanelOpen(isOpen) { + panel.classList.toggle('github-chat-hidden', !isOpen); + toggle.setAttribute('aria-expanded', String(isOpen)); + if (isOpen) { + renderMessages(); + input.focus(); + } + } + + toggle.addEventListener('click', () => { + setPanelOpen(panel.classList.contains('github-chat-hidden')); + }); + + close.addEventListener('click', () => setPanelOpen(false)); + + form.addEventListener('submit', (event) => { + event.preventDefault(); + const text = input.value.trim(); + if (!text) return; + + const savedMessages = getSavedChatMessages(storageKey); + savedMessages.push({ + text, + createdAt: new Date().toLocaleString(), + }); + localStorage.setItem(storageKey, JSON.stringify(savedMessages)); + input.value = ''; + renderMessages(); + }); +} + +function getGithubChatContext() { + const [, owner, repo] = window.location.pathname.split('/'); + if (owner && repo) { + return { + key: `${owner}/${repo}`, + label: `${owner}/${repo}`, + }; + } + + return { + key: window.location.pathname || '/', + label: 'github.com', + }; +} + +function getSavedChatMessages(storageKey) { + try { + const messages = JSON.parse(localStorage.getItem(storageKey) || '[]'); + return Array.isArray(messages) ? messages : []; + } catch (error) { + return []; + } +} diff --git a/manifest.json b/manifest.json index db0a183..6a3f644 100644 --- a/manifest.json +++ b/manifest.json @@ -27,6 +27,17 @@ "story-list.css", "story-view.css" ] + }, + { + "matches": [ + "https://github.com/*" + ], + "js": [ + "github-chat.js" + ], + "css": [ + "github-chat.css" + ] } ], "icons": {