From 79b15927bf1ad6c6ab6633cb45d1532e87260dc0 Mon Sep 17 00:00:00 2001 From: qinscode Date: Tue, 20 May 2025 21:30:31 +0800 Subject: [PATCH 1/5] ci: remove unused platform configurations - Remove macOS x86_64 and Ubuntu configurations from publish workflow - Keep only aarch64-apple-darwin and windows-latest platform configurations --- .github/workflows/publish.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a1dcb34..0882bdc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,10 +15,6 @@ jobs: include: - platform: 'macos-latest' args: '--target aarch64-apple-darwin' - - platform: 'macos-latest' - args: '--target x86_64-apple-darwin' - - platform: 'ubuntu-22.04' - args: '' - platform: 'windows-latest' args: '' From 04d097635f2e0e6f17fb30149e3929cd353a1cc0 Mon Sep 17 00:00:00 2001 From: qinscode Date: Tue, 20 May 2025 21:37:45 +0800 Subject: [PATCH 2/5] feat(layout): add footer with tech stack chips and remove GitHub text shadow animation - Add footer component to the main layout - Include tech stack chips: React, Tauri, TypeScript, and Vite - Add GitHub icon link and other footer links (Issues, MIT License) - Remove text shadow animation from GitHub repository analyzer text --- src/components/layout/Root.tsx | 109 ++++++++++++++++++++++++++++++++- src/pages/GitHub.tsx | 16 +---- 2 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/components/layout/Root.tsx b/src/components/layout/Root.tsx index 5d9df8f..8555c15 100644 --- a/src/components/layout/Root.tsx +++ b/src/components/layout/Root.tsx @@ -1,5 +1,15 @@ -import { CssBaseline, ThemeProvider, createTheme } from "@mui/material"; +import { + CssBaseline, + ThemeProvider, + createTheme, + Box, + Typography, + Link, + Stack, + Chip, +} from "@mui/material"; import { Outlet } from "@tanstack/react-router"; +import GitHubIcon from "@mui/icons-material/GitHub"; // Create custom theme const theme = createTheme({ @@ -35,16 +45,109 @@ export default function Root(): React.ReactElement {
{/* Light static background instead of heavy blur effect */} -
+
+ + + + + + + + + + + + GitHub + + + Issues + + + MIT License + + + + + © {new Date().getFullYear()} GitHub Repository Analyzer v0.4.0 + Created with ❤️ by Jack Qin + + +
); diff --git a/src/pages/GitHub.tsx b/src/pages/GitHub.tsx index 0e7adfa..032f512 100644 --- a/src/pages/GitHub.tsx +++ b/src/pages/GitHub.tsx @@ -29,21 +29,7 @@ export const GitHub = () => { "0 2px 10px rgba(79,70,229,0.4), 0 0 20px rgba(59,130,246,0.12)", letterSpacing: "-0.5px", marginBottom: "0.5rem", - animation: "pulse 2s infinite ease-in-out", - "@keyframes pulse": { - "0%": { - textShadow: - "0 2px 10px rgba(79,70,229,0.4), 0 0 20px rgba(59,130,246,0.2)", - }, - "50%": { - textShadow: - "0 2px 20px rgba(79,70,229,0.6), 0 0 30px rgba(59,130,246,0.4)", - }, - "100%": { - textShadow: - "0 2px 10px rgba(79,70,229,0.4), 0 0 20px rgba(59,130,246,0.2)", - }, - }, + }} > GitHub Repository Analyzer From 2d9a11b7ae47fc8626e7397bce37de714e85bcad Mon Sep 17 00:00:00 2001 From: qinscode Date: Tue, 20 May 2025 21:49:06 +0800 Subject: [PATCH 3/5] refactor(BatchResults): remove background gradients for improved performance --- src/components/github/results/BatchResults.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/github/results/BatchResults.tsx b/src/components/github/results/BatchResults.tsx index 47e7a16..1a5eb47 100644 --- a/src/components/github/results/BatchResults.tsx +++ b/src/components/github/results/BatchResults.tsx @@ -51,8 +51,6 @@ function BatchResults({ results }: BatchResultsProps) { left: -150, width: 300, height: 300, - background: - "radial-gradient(circle, rgba(59, 130, 246, 0.05) 0%, rgba(59, 130, 246, 0) 70%)", borderRadius: "50%", zIndex: -1, }, @@ -63,8 +61,6 @@ function BatchResults({ results }: BatchResultsProps) { right: -150, width: 300, height: 300, - background: - "radial-gradient(circle, rgba(79, 70, 229, 0.05) 0%, rgba(79, 70, 229, 0) 70%)", borderRadius: "50%", zIndex: -1, }, From 560b10aaaa4b9a08c8c17525f23344f7f18757c9 Mon Sep 17 00:00:00 2001 From: qinscode Date: Tue, 20 May 2025 21:54:09 +0800 Subject: [PATCH 4/5] feat(styles): remove background gradients and adjust z-index - Remove background gradient from form overlay - Adjust z-index for better layering - Remove radial gradient from body in tailwind.css --- src/styles/FormStyles.css | 6 ++---- src/styles/tailwind.css | 5 +---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/styles/FormStyles.css b/src/styles/FormStyles.css index fa36295..731abb8 100644 --- a/src/styles/FormStyles.css +++ b/src/styles/FormStyles.css @@ -23,7 +23,6 @@ left: 0; right: 0; bottom: 0; - background: linear-gradient(120deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.05) 100%); z-index: -1; opacity: 0; transition: opacity 0.5s ease; @@ -50,9 +49,9 @@ left: -150px; width: 300px; height: 300px; - background: radial-gradient(circle, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0) 70%); border-radius: 50%; - z-index: -1; + background: radial-gradient(circle, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0) 70%); + z-index: -1; animation: pulse 15s infinite alternate ease-in-out; } @@ -63,7 +62,6 @@ right: -100px; width: 250px; height: 250px; - background: radial-gradient(circle, rgba(79, 70, 229, 0.06) 0%, rgba(79, 70, 229, 0) 70%); border-radius: 50%; z-index: -1; animation: pulse 12s infinite alternate-reverse ease-in-out; diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css index 4d1b406..8d1ed67 100644 --- a/src/styles/tailwind.css +++ b/src/styles/tailwind.css @@ -6,8 +6,5 @@ html, body, #root { min-height: 100vh; } - - body { - background: radial-gradient(circle, rgba(79, 70, 229, 0.05) 0%, rgba(79, 70, 229, 0) 70%); - } + } From 804fa6aba5bad57ed2e4e8bd6c549e3ce51ae5d2 Mon Sep 17 00:00:00 2001 From: qinscode Date: Tue, 20 May 2025 22:55:31 +0800 Subject: [PATCH 5/5] style(github): update repo card shadow effect - Remove BatchRepoForm component and related styles- Update RepoCard component and add new styles - Update GitHub page version number to v0.4.3 --- .github/workflows/publish.yml | 2 +- src/components/github/forms/BatchRepoForm.tsx | 382 ------------------ src/components/github/results/RepoCard.css | 51 +++ src/components/github/results/RepoCard.tsx | 26 +- src/components/layout/Root.tsx | 2 +- .../github/analysis/RepoAnalysisForm.tsx | 2 +- src/pages/GitHub.tsx | 3 +- src/styles/FormStyles.css | 77 +--- 8 files changed, 70 insertions(+), 475 deletions(-) delete mode 100644 src/components/github/forms/BatchRepoForm.tsx create mode 100644 src/components/github/results/RepoCard.css diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0882bdc..4ec69dc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -59,7 +59,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tagName: app-v__VERSION__ + tagName: release-v__VERSION__ releaseName: 'GH Analyzer v__VERSION__' releaseBody: 'See the assets to download this version and install.' releaseDraft: true diff --git a/src/components/github/forms/BatchRepoForm.tsx b/src/components/github/forms/BatchRepoForm.tsx deleted file mode 100644 index 48b0294..0000000 --- a/src/components/github/forms/BatchRepoForm.tsx +++ /dev/null @@ -1,382 +0,0 @@ -import { useState, useEffect } from "react"; -import { - Box, - TextField, - Typography, - InputAdornment, - Card, - CardContent, - Grow, -} from "@mui/material"; -import GitHubIcon from "@mui/icons-material/GitHub"; -import KeyIcon from "@mui/icons-material/Key"; -import ViewListIcon from "@mui/icons-material/ViewList"; - -import { fetchRepositoryData, parseRepoUrl } from "@/services/github"; -import "@/styles/FormStyles.css"; -import type { - RepoListItem, - RepoResult, - BatchRepoFormProps, -} from "@/types/github"; -import RepoStatusList from "./RepoStatusList"; -import ProcessingProgress from "./ProcessingProgress"; -import AnalysisOptions from "./AnalysisOptions"; -import FormActions from "./FormActions"; - -const BatchRepoForm: React.FC = ({ onDataFetched }) => { - // Form state - const [repoUrls, setRepoUrls] = useState(""); - const [token, setToken] = useState(""); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const [success, setSuccess] = useState(false); - const [hideMergeCommits, setHideMergeCommits] = useState(true); - - // Batch processing state - const [repoItems, setRepoItems] = useState>([]); - // @ts-ignore - const [results, setResults] = useState>([]); - const [currentIndex, setCurrentIndex] = useState(-1); - const [progress, setProgress] = useState(0); - - // Get the preset GitHub token from environment variables - useEffect(() => { - const presetToken = import.meta.env["VITE_GITHUB_API_TOKEN"]; - if (presetToken) { - setToken(presetToken); - } - }, []); - - // Check if there's a preset token - const hasPresetToken = !!import.meta.env["VITE_GITHUB_API_TOKEN"]; - - const extractRepoName = (url: string): string => { - const match = url.match(/github\.com\/([^/]+)\/([^/]+)/); - if (match) { - return `${match[1]}/${match[2]}`; - } - - // Handle owner/repo format - const parts = url.split("/"); - if (parts.length === 2) { - return url; - } - - return url; - }; - - const handleSubmit = async (event: React.FormEvent): Promise => { - event.preventDefault(); - - if (!repoUrls.trim()) { - setError("Please enter GitHub repository URLs"); - return; - } - - if (!token.trim()) { - setError("Please enter a GitHub token"); - return; - } - - // Parse repository URLs - const urlList = repoUrls - .trim() - .split("\n") - .filter((url) => url.trim() !== ""); - - if (urlList.length === 0) { - setError("Please enter at least one valid GitHub repository URL"); - return; - } - - setLoading(true); - setError(null); - setSuccess(false); - setResults([]); - setCurrentIndex(-1); - setProgress(0); - - try { - // Process each URL - const items: Array = []; - const invalidUrls: Array = []; - - // Validate URLs first - for (const url of urlList) { - const trimmedUrl = url.trim(); - const repoInfo = parseRepoUrl(trimmedUrl); - - if (!repoInfo) { - invalidUrls.push(`Invalid repository URL format: ${trimmedUrl}`); - continue; - } - - // Check for duplicates - if ( - items.some( - (repo) => repo.url.toLowerCase() === trimmedUrl.toLowerCase() - ) - ) { - invalidUrls.push(`Duplicate repository URL: ${trimmedUrl}`); - continue; - } - - items.push({ - id: - Date.now().toString() + Math.random().toString(36).substring(2, 9), - url: trimmedUrl, - status: "pending", - }); - } - - if (invalidUrls.length > 0) { - const errorMessage = - invalidUrls.length <= 3 - ? `Issues with some repositories: ${invalidUrls.join("; ")}` - : `Issues with ${invalidUrls.length} repositories. First few: ${invalidUrls.slice(0, 3).join("; ")}...`; - setError(errorMessage); - - if (items.length === 0) { - setLoading(false); - return; - } - } - - setRepoItems(items); - const batchResults: Array = []; - - // Process repositories sequentially - for (let index = 0; index < items.length; index++) { - setCurrentIndex(index); - setProgress((index / items.length) * 100); - - // Update status to processing - setRepoItems((previousItems) => { - const updatedItems = [...previousItems]; - const item = updatedItems[index]; - if (item) { - updatedItems[index] = { ...item, status: "processing" }; - } - return updatedItems; - }); - - try { - const currentItem = items[index]; - if (!currentItem) continue; - - // Pass filtering option to API - const data = await fetchRepositoryData(currentItem.url, token, { - hideMergeCommits, - }); - - const result: RepoResult = { - repoUrl: currentItem.url, - repoName: extractRepoName(currentItem.url), - commits: Object.values(data.commits).flat().length, - issues: Object.values(data.issues).flat().length, - prs: Object.values(data.prs).flat().length, - contributors: Object.keys(data.commits).length, - data, - }; - - batchResults.push(result); - - // Update status to completed - setRepoItems((previousItems) => { - const updatedItems = [...previousItems]; - const item = updatedItems[index]; - if (item) { - updatedItems[index] = { - ...item, - status: "completed", - result, - }; - } - return updatedItems; - }); - } catch (error_) { - console.error( - `Error processing ${items[index]?.url || "unknown repository"}:`, - error_ - ); - - // Update status to error - setRepoItems((previousItems) => { - const updatedItems = [...previousItems]; - const item = updatedItems[index]; - if (item) { - updatedItems[index] = { - ...item, - status: "error", - error: (error_ as Error).message, - }; - } - return updatedItems; - }); - } - } - - setProgress(100); - setResults(batchResults); - onDataFetched(batchResults); - setSuccess(true); - } catch (error_) { - setError(`Batch analysis failed: ${(error_ as Error).message}`); - console.error(error_); - } finally { - setLoading(false); - } - }; - - const clearForm = (): void => { - setRepoUrls(""); - setError(null); - setSuccess(false); - setResults([]); - setRepoItems([]); - setCurrentIndex(-1); - setProgress(0); - }; - - return ( - - - - - Analyze Multiple Repositories - - - - - - - - - - ), - }} - error={ - !!error && - (error.includes("repository") || error.includes("URL")) - } - helperText={ - error && - (error.includes("repository") || error.includes("URL")) - ? error - : "Enter one repository URL per line" - } - placeholder="Enter repository URLs (one per line) -Example: -https://github.com/facebook/react -microsoft/typescript" - onChange={(event_) => { - setRepoUrls(event_.target.value); - if (error) setError(null); - }} - /> - - - {!hasPresetToken && ( - - - - - - - ), - }} - helperText={ - error && error.includes("token") - ? error - : "GitHub personal access token with repo scope" - } - onChange={(event_) => { - setToken(event_.target.value); - if (error) setError(null); - }} - /> - - )} - - { - setHideMergeCommits(checked); - }} - /> - - - - - - - - - - - Batch processing allows you to analyze multiple repositories at - once. - - - - - - - ); -}; - -export default BatchRepoForm; diff --git a/src/components/github/results/RepoCard.css b/src/components/github/results/RepoCard.css new file mode 100644 index 0000000..f50a372 --- /dev/null +++ b/src/components/github/results/RepoCard.css @@ -0,0 +1,51 @@ +.MuiCard-root.repo-card { + border-radius: 20px !important; + overflow: hidden !important; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.98), rgba(249, 250, 251, 0.95)) !important; + backdrop-filter: blur(10px) !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; + border: 1px solid rgba(255, 255, 255, 0.7) !important; + box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), + 0 8px 10px -6px rgba(0, 0, 0, 0.1), + 0 0 5px 2px rgba(59, 130, 246, 0.08) !important; + margin-bottom: 2.5rem !important; + position: relative !important; +} + + + +.MuiCard-root.repo-card:hover::after { + opacity: 0.8 !important; +} + +.MuiCard-root.repo-card:hover { + transform: translateY(-5px) !important; + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.3), + 0 20px 30px -15px rgba(59, 130, 246, 0.25), + 0 0 20px 8px rgba(79, 70, 229, 0.18) !important; +} + +.MuiCard-root.repo-card-expanded { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25), + 0 15px 25px -10px rgba(59, 130, 246, 0.2), + 0 0 15px 5px rgba(79, 70, 229, 0.15) !important; + transform: none !important; +} + +.MuiCard-root.repo-card-expanded:hover { + transform: none !important; +} + +.MuiCard-root.repo-card::before { + content: ""; + position: absolute; + inset: 0; + border-radius: 20px; + background: rgba(0, 0, 0, 0.08); + filter: blur(12px); + z-index: -1; +} + +.MuiCard-root.repo-card-expanded::before { + opacity: 1 !important; +} \ No newline at end of file diff --git a/src/components/github/results/RepoCard.tsx b/src/components/github/results/RepoCard.tsx index 749b139..f39fa05 100644 --- a/src/components/github/results/RepoCard.tsx +++ b/src/components/github/results/RepoCard.tsx @@ -16,6 +16,7 @@ import { RepoResult } from "@/types/github"; import { RepoStats } from "./RepoStats"; import { RepoActions } from "./RepoActions"; import RepoResults from "../repo-analysis/RepoResults"; +import "./RepoCard.css"; interface RepoCardProps { result: RepoResult; @@ -30,29 +31,25 @@ export const RepoCard = ({ result }: RepoCardProps) => { setExpandedRepo(expandedRepo === repoUrl ? null : repoUrl); }; + const isExpanded = expandedRepo === result.repoUrl; + return ( { right: 0, height: { xs: "2px", sm: "2px", md: "3px" }, background: "linear-gradient(90deg, #3B82F6, #4F46E5)", - opacity: expandedRepo === result.repoUrl ? 1 : 0, + opacity: isExpanded ? 1 : 0, transition: "opacity 0.3s ease", }, - mb: { xs: 1.5, sm: 2, md: 2.5 }, }} > - © {new Date().getFullYear()} GitHub Repository Analyzer v0.4.0 + © {new Date().getFullYear()} GitHub Repository Analyzer v0.4.5 Created with ❤️ by Jack Qin diff --git a/src/features/github/analysis/RepoAnalysisForm.tsx b/src/features/github/analysis/RepoAnalysisForm.tsx index 851b320..e985a75 100644 --- a/src/features/github/analysis/RepoAnalysisForm.tsx +++ b/src/features/github/analysis/RepoAnalysisForm.tsx @@ -74,7 +74,7 @@ const RepoAnalysisForm = () => { return ( - +
diff --git a/src/pages/GitHub.tsx b/src/pages/GitHub.tsx index 032f512..e8cc902 100644 --- a/src/pages/GitHub.tsx +++ b/src/pages/GitHub.tsx @@ -29,7 +29,6 @@ export const GitHub = () => { "0 2px 10px rgba(79,70,229,0.4), 0 0 20px rgba(59,130,246,0.12)", letterSpacing: "-0.5px", marginBottom: "0.5rem", - }} > GitHub Repository Analyzer @@ -44,7 +43,7 @@ export const GitHub = () => { marginBottom: "1rem", }} > - v0.4.0 + v0.4.5 diff --git a/src/styles/FormStyles.css b/src/styles/FormStyles.css index 731abb8..ae972d5 100644 --- a/src/styles/FormStyles.css +++ b/src/styles/FormStyles.css @@ -1,71 +1,17 @@ -.form-card { - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - border-radius: 16px !important; - overflow: hidden; - background: linear-gradient(135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.25)) !important; - backdrop-filter: blur(20px) !important; - border: 1.5px solid rgba(255, 255, 255, 0.5) !important; - box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.08), 0 4px 8px -2px rgba(0, 0, 0, 0.04) !important; - position: relative; - z-index: 1; -} - -.form-card:hover { - transform: translateY(-3px); - box-shadow: 0 20px 30px -5px rgba(59, 130, 246, 0.12), 0 10px 15px -5px rgba(59, 130, 246, 0.08) !important; - border-color: rgba(255, 255, 255, 0.7) !important; -} - -.form-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: -1; - opacity: 0; - transition: opacity 0.5s ease; -} -.form-card:hover::before { - opacity: 1; +.transparent-bg { + background-color: transparent !important; } - .form-container { - position: relative; - overflow: hidden; + background-color: transparent !important; } + .MuiPaper-elevation { box-shadow: none !important; -}s - -.form-container::before { - content: ""; - position: absolute; - top: -100px; - left: -150px; - width: 300px; - height: 300px; - border-radius: 50%; - background: radial-gradient(circle, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0) 70%); - z-index: -1; - animation: pulse 15s infinite alternate ease-in-out; } -.form-container::after { - content: ""; - position: absolute; - bottom: -50px; - right: -100px; - width: 250px; - height: 250px; - border-radius: 50%; - z-index: -1; - animation: pulse 12s infinite alternate-reverse ease-in-out; -} @keyframes pulse { 0% { opacity: 0.5; transform: scale(1); } @@ -447,21 +393,6 @@ } } -/* 数据展示卡片 */ -.data-card { - border-radius: 12px; - overflow: hidden; - background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(249, 250, 251, 0.9)); - backdrop-filter: blur(8px); - border: 1px solid rgba(255, 255, 255, 0.7); - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.02); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.data-card:hover { - transform: translateY(-3px); - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.05), 0 10px 10px -5px rgba(0, 0, 0, 0.04); -} /* 动画效果 */ @keyframes fadeInUp {