From d8bacd093dc7545c5028d1ae9c2424f2d0877d1d Mon Sep 17 00:00:00 2001 From: Ryo Fujimura Date: Thu, 13 Mar 2025 15:04:13 -0700 Subject: [PATCH 1/9] ui, option to add private repo and personal access token --- src/app/(site)/Options.tsx | 344 ++++++++++++++++++++++++------------- 1 file changed, 220 insertions(+), 124 deletions(-) diff --git a/src/app/(site)/Options.tsx b/src/app/(site)/Options.tsx index dbeea17..62eecd5 100644 --- a/src/app/(site)/Options.tsx +++ b/src/app/(site)/Options.tsx @@ -1,135 +1,231 @@ 'use client' +import { useState, useEffect } from 'react' import { store, DISPLAYS, type Theme, type Display } from '@/lib/store' import Input from '@/ui/Input' import { debounce } from '@/lib/utils' import { - VscSettings, - VscFileCode, - VscRepo, - VscSymbolColor, - VscEye, - VscEyeClosed, - VscPaintcan, - VscCode, - VscListSelection, - VscListOrdered, + VscSettings, + VscFileCode, + VscRepo, + VscSymbolColor, + VscEye, + VscEyeClosed, + VscPaintcan, + VscCode, + VscListSelection, + VscListOrdered, + VscLock, + VscUnlock, } from 'react-icons/vsc' import { bundledThemes } from 'shiki' import Checkbox from '@/ui/Checkbox' export default function Options() { - const { - repo, - path, - theme, - lang, - display, - lineNums, - highlight, - scrollTo, - setRepo, - setPath, - setTheme, - setLang, - setDisplay, - setLineNums, - setHighlight, - setScrollTo, - } = store() - - const ext = path?.split('.').at(-1) ?? '' - - return ( -
- - Options - - -
- setRepo(e.target.value))} - pattern=".+/.+" - required - /> - - setPath(e.target.value))} - className="group-[:has(.view-file-source:hover)_input]/root:border-black/30" - required - /> - - - - - - setLang(e.target.value))} - placeholder={ext} - /> - - - - - - setLineNums(e.target.checked)} - /> - - setHighlight(e.target.value))} - pattern="((\d+|\d+-\d+),)*(\d+|\d+-\d+)" - placeholder="lines (e.g. 5,14-19)" - /> - - {highlight && ( - setScrollTo(e.target.checked)} - /> - )} -
-
- ) -} + const { + repo, + path, + theme, + lang, + display, + lineNums, + highlight, + scrollTo, + setRepo, + setPath, + setTheme, + setLang, + setDisplay, + setLineNums, + setHighlight, + setScrollTo, + } = store() + + const ext = path?.split('.').at(-1) ?? '' + + // State for private repo access + const [accountType, setAccountType] = useState<'users' | 'orgs'>('users') + const [token, setToken] = useState('') + const [showTokenInput, setShowTokenInput] = useState(false) + const [showToken, setShowToken] = useState(false) + + // Split repo into owner and repoName + const [owner, repoName] = repo ? repo.split('/') : ['', ''] + + // Debounced function to fetch private repo data + const fetchPrivateRepo = debounce((tokenValue: string) => { + if (tokenValue && owner && repoName) { + console.log('Fetching private repo with:', { owner, repoName, accountType, token: tokenValue }) + // Future: Implement API call to fetch private repo data here + } + }, 500) + + // Automatically fetch when token changes + useEffect(() => { + if (showTokenInput && token) { + fetchPrivateRepo(token) + } + }, [token, showTokenInput, owner, repoName, accountType]) + + return ( +
+ + Options + + +
+ {/* Existing Repo Input */} + setRepo(e.target.value))} + pattern=".+/.+" + required + /> + + setPath(e.target.value))} + className="group-[:has(.view-file-source:hover)_input]/root:border-black/30" + required + /> + + {/* Private Repo Options */} +
+
+ + +
+ + + + {showTokenInput && ( +
+ setToken(e.target.value)} // No debounce here, handled by useEffect + type={showToken ? 'text' : 'password'} + placeholder="ghp_xxxxxxxxxxxxxxxx" + /> + setShowToken(!showToken)} + className="text-sm text-blue-500 cursor-pointer hover:underline" + > + {showToken ? 'Hide token' : 'Show token'} + +

+ Use a token with repo scope from{' '} + + GitHub Settings + . Fetches automatically as you type. +

+
+ )} +
+ + {/* Remaining Existing Inputs */} + + + + + setLang(e.target.value))} + placeholder={ext} + /> + + + + + + setLineNums(e.target.checked)} + /> + + setHighlight(e.target.value))} + pattern="((\d+|\d+-\d+),)*(\d+|\d+-\d+)" + placeholder="lines (e.g. 5,14-19)" + /> + + {highlight && ( + setScrollTo(e.target.checked)} + /> + )} +
+
+ ) +} \ No newline at end of file From b857c32304464f305e4f699de60a59aadfaecf84 Mon Sep 17 00:00:00 2001 From: Ryo Fujimura Date: Thu, 13 Mar 2025 15:55:36 -0700 Subject: [PATCH 2/9] github private repo code --- package-lock.json | 4 ++-- src/app/(site)/Options.tsx | 32 +++++++++++++------------------- src/lib/octokit/client.ts | 31 ++++++++++++++++++++++++++++++- src/lib/octokit/github.ts | 32 ++++++++++++++++++++++++++++++++ src/lib/store.ts | 10 +++++++++- 5 files changed, 86 insertions(+), 23 deletions(-) create mode 100644 src/lib/octokit/github.ts diff --git a/package-lock.json b/package-lock.json index d918011..501a3b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "github-iframe", - "version": "0.7.8", + "version": "0.8.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "github-iframe", - "version": "0.7.8", + "version": "0.8.3", "dependencies": { "@vercel/analytics": "^1.4.1", "clsx": "^2.1.1", diff --git a/src/app/(site)/Options.tsx b/src/app/(site)/Options.tsx index 62eecd5..e1632eb 100644 --- a/src/app/(site)/Options.tsx +++ b/src/app/(site)/Options.tsx @@ -39,33 +39,30 @@ export default function Options() { setLineNums, setHighlight, setScrollTo, + setToken, // New + setAccountType, // New } = store() const ext = path?.split('.').at(-1) ?? '' // State for private repo access - const [accountType, setAccountType] = useState<'users' | 'orgs'>('users') - const [token, setToken] = useState('') + const [accountType, setLocalAccountType] = useState<'users' | 'orgs'>('users') + const [token, setLocalToken] = useState('') const [showTokenInput, setShowTokenInput] = useState(false) const [showToken, setShowToken] = useState(false) // Split repo into owner and repoName const [owner, repoName] = repo ? repo.split('/') : ['', ''] - // Debounced function to fetch private repo data - const fetchPrivateRepo = debounce((tokenValue: string) => { - if (tokenValue && owner && repoName) { - console.log('Fetching private repo with:', { owner, repoName, accountType, token: tokenValue }) - // Future: Implement API call to fetch private repo data here - } - }, 500) - - // Automatically fetch when token changes + // Sync local state with store useEffect(() => { if (showTokenInput && token) { - fetchPrivateRepo(token) + setToken(token) + setAccountType(accountType) + } else { + setToken('') // Clear token in store when hidden } - }, [token, showTokenInput, owner, repoName, accountType]) + }, [token, showTokenInput, accountType, setToken, setAccountType]) return (
@@ -74,7 +71,6 @@ export default function Options() {
- {/* Existing Repo Input */} - {/* Private Repo Options */}
- {/* Remaining Existing Inputs */} setLocalAccountType('users')} - className="mr-1" - /> - User - - -
-