diff --git a/README.md b/README.md index 0af0dd3..8d8060c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # GitHub Stories -View stories on your GitHub dashboard. +View stories on your GitHub dashboard and open a lightweight chat panel on any GitHub page. No uploads required. Just [install](#how-to-install) and visit [github.com](https://github.com). +The chat button appears in the lower-right corner on `github.com/*` pages. Open it to write page-specific notes, then hide it again without leaving GitHub. +  ## How to Install diff --git a/content-script.js b/content-script.js index 78cdb14..230b0aa 100644 --- a/content-script.js +++ b/content-script.js @@ -31,6 +31,100 @@ const UPDATE_PROGRESS_BAR_VALUE = time / (AUTOMATIC_SCROLL_DELAY / PROGRESS_BAR_UPDATE_DELAY - 5); let storyViewOpen = false; +initGithubChat(); + +function initGithubChat() { + if (window.top !== window || document.getElementById('github-chat-root')) { + return; + } + + const chatRoot = document.createElement('div'); + chatRoot.id = 'github-chat-root'; + chatRoot.innerHTML = ` + + + `; + + document.documentElement.appendChild(chatRoot); + + const toggle = chatRoot.querySelector('.github-chat-toggle'); + const panel = chatRoot.querySelector('.github-chat-panel'); + const close = chatRoot.querySelector('.github-chat-close'); + const form = chatRoot.querySelector('.github-chat-form'); + const input = chatRoot.querySelector('.github-chat-input'); + const messages = chatRoot.querySelector('.github-chat-messages'); + + const pageKey = `github-chat:${location.pathname}`; + const savedMessages = loadChatMessages(pageKey); + renderChatMessages(messages, savedMessages); + + toggle.addEventListener('click', () => { + const isHidden = panel.classList.toggle('hidden'); + toggle.setAttribute('aria-expanded', String(!isHidden)); + if (!isHidden) input.focus(); + }); + + close.addEventListener('click', () => { + panel.classList.add('hidden'); + toggle.setAttribute('aria-expanded', 'false'); + toggle.focus(); + }); + + form.addEventListener('submit', (event) => { + event.preventDefault(); + const text = input.value.trim(); + if (!text) return; + + const nextMessages = [ + ...loadChatMessages(pageKey), + { text, createdAt: new Date().toISOString() }, + ]; + saveChatMessages(pageKey, nextMessages); + renderChatMessages(messages, nextMessages); + input.value = ''; + }); +} + +function loadChatMessages(pageKey) { + try { + return JSON.parse(localStorage.getItem(pageKey) || '[]'); + } catch (error) { + return []; + } +} + +function saveChatMessages(pageKey, messages) { + localStorage.setItem(pageKey, JSON.stringify(messages.slice(-50))); +} + +function renderChatMessages(container, messages) { + if (messages.length === 0) { + container.innerHTML = '
No messages yet.
'; + return; + } + + container.innerHTML = ''; + messages.forEach((message) => { + const item = document.createElement('div'); + item.className = 'github-chat-message'; + item.innerText = message.text; + container.appendChild(item); + }); + container.scrollTop = container.scrollHeight; +} + function getActionFullText(element){ let fullText = ''; diff --git a/manifest.json b/manifest.json index db0a183..e12f406 100644 --- a/manifest.json +++ b/manifest.json @@ -17,8 +17,7 @@ "content_scripts": [ { "matches": [ - "https://github.com/", - "https://github.com/orgs/*" + "https://github.com/*" ], "js": [ "content-script.js" diff --git a/story-list.css b/story-list.css index e33df07..e36fc47 100644 --- a/story-list.css +++ b/story-list.css @@ -53,3 +53,101 @@ img.user-story-img { border-radius: 50%; width: 56px; } + +#github-chat-root { + position: fixed; + right: 24px; + bottom: 24px; + z-index: 99999; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +.github-chat-toggle { + background: #2da44e; + border: 0; + border-radius: 999px; + box-shadow: 0 8px 24px rgba(27, 31, 36, 0.24); + color: #ffffff; + cursor: pointer; + font-weight: 600; + min-height: 44px; + padding: 0 18px; +} + +.github-chat-panel { + background: #ffffff; + border: 1px solid #d0d7de; + border-radius: 8px; + bottom: 56px; + box-shadow: 0 16px 48px rgba(27, 31, 36, 0.2); + color: #24292f; + display: flex; + flex-direction: column; + height: min(440px, calc(100vh - 120px)); + overflow: hidden; + position: absolute; + right: 0; + width: min(360px, calc(100vw - 32px)); +} + +.github-chat-header { + align-items: center; + border-bottom: 1px solid #d0d7de; + display: flex; + justify-content: space-between; + padding: 12px 14px; +} + +.github-chat-close { + background: transparent; + border: 0; + color: #57606a; + cursor: pointer; + font-size: 22px; + line-height: 1; +} + +.github-chat-messages { + flex: 1; + overflow-y: auto; + padding: 14px; +} + +.github-chat-empty { + color: #57606a; + margin: 0; +} + +.github-chat-message { + background: #f6f8fa; + border: 1px solid #d8dee4; + border-radius: 8px; + margin-bottom: 8px; + padding: 8px 10px; + white-space: pre-wrap; +} + +.github-chat-form { + border-top: 1px solid #d0d7de; + display: flex; + gap: 8px; + padding: 10px; +} + +.github-chat-input { + border: 1px solid #d0d7de; + border-radius: 6px; + flex: 1; + min-width: 0; + padding: 8px; +} + +.github-chat-send { + background: #0969da; + border: 0; + border-radius: 6px; + color: #ffffff; + cursor: pointer; + font-weight: 600; + padding: 0 12px; +}