From c5e80c10140f28d0314749fe408f99c15167cfe2 Mon Sep 17 00:00:00 2001 From: Mtao Date: Sun, 8 Mar 2026 13:58:08 +0800 Subject: [PATCH 1/2] remove github star feature --- dist/index.html | 36 +++++++++++------------ src/components/RepositoryCard.tsx | 49 +++++++++++++++++++++++++++++-- src/services/githubApi.ts | 10 +++++-- src/store/useAppStore.ts | 5 ++++ 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/dist/index.html b/dist/index.html index 61c41c13..b0f3f514 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,19 +1,19 @@ - - - - - - - GitHub Stars Manager - AI-Powered Repository Management - - - - - - - - - -
- + + + + + + + GitHub Stars Manager - AI-Powered Repository Management + + + + + + + + + +
+ \ No newline at end of file diff --git a/src/components/RepositoryCard.tsx b/src/components/RepositoryCard.tsx index 51f05053..bcf10bc2 100644 --- a/src/components/RepositoryCard.tsx +++ b/src/components/RepositoryCard.tsx @@ -28,12 +28,14 @@ export const RepositoryCard: React.FC = ({ setLoading, language, customCategories, - updateRepository + updateRepository, + deleteRepository } = useAppStore(); const [editModalOpen, setEditModalOpen] = useState(false); const [showTooltip, setShowTooltip] = useState(false); const [isTextTruncated, setIsTextTruncated] = useState(false); + const [unstarring, setUnstarring] = useState(false); const descriptionRef = useRef(null); @@ -311,6 +313,41 @@ export const RepositoryCard: React.FC = ({ const t = (zh: string, en: string) => language === 'zh' ? zh : en; + const handleUnstar = async () => { + if (!githubToken) { + alert('GitHub token not found. Please login again.'); + return; + } + + const confirmMessage = language === 'zh' + ? `确定要取消 Star "${repository.full_name}" 吗?\n\n这将会从您的 GitHub 收藏中移除该仓库。` + : `Are you sure you want to unstar "${repository.full_name}"?\n\nThis will remove the repository from your GitHub stars.`; + + if (!confirm(confirmMessage)) { + return; + } + + setUnstarring(true); + try { + const githubApi = new GitHubApiService(githubToken); + const [owner, repo] = repository.full_name.split('/'); + await githubApi.unstarRepository(owner, repo); + deleteRepository(repository.id); + const successMessage = language === 'zh' + ? '已成功取消 Star' + : 'Successfully unstarred'; + alert(successMessage); + } catch (error) { + console.error('Failed to unstar repository:', error); + const errorMessage = language === 'zh' + ? '取消 Star 失败,请检查网络连接或重新登录。' + : 'Failed to unstar repository. Please check your network connection or login again.'; + alert(errorMessage); + } finally { + setUnstarring(false); + } + }; + return (
{/* Header - Repository Info */} @@ -367,7 +404,7 @@ export const RepositoryCard: React.FC = ({
- {/* Right side: Zread/DeepWiki and GitHub Links */} + {/* Right side: Zread/DeepWiki, GitHub Links, and Unstar */}
= ({ > +
diff --git a/src/services/githubApi.ts b/src/services/githubApi.ts index 71621572..db41add9 100644 --- a/src/services/githubApi.ts +++ b/src/services/githubApi.ts @@ -27,8 +27,8 @@ export class GitHubApiService { throw new Error(`GitHub API error: ${response.status} ${response.statusText}`); } - const data = await response.json(); - + const data = response.status === 204 ? null : await response.json(); + // 如果是starred repositories的响应,需要处理特殊格式 if (endpoint.includes('/user/starred') && Array.isArray(data)) { return data.map((item: any) => { @@ -191,6 +191,12 @@ export class GitHubApiService { } } + async unstarRepository(owner: string, repo: string): Promise { + await this.makeRequest(`/user/starred/${owner}/${repo}`, { + method: 'DELETE', + }); + } + async checkRateLimit(): Promise<{ remaining: number; reset: number }> { const response = await this.makeRequest('/rate_limit'); return { diff --git a/src/store/useAppStore.ts b/src/store/useAppStore.ts index 45d8c553..fd2358b0 100644 --- a/src/store/useAppStore.ts +++ b/src/store/useAppStore.ts @@ -14,6 +14,7 @@ interface AppActions { updateRepository: (repo: Repository) => void; setLoading: (loading: boolean) => void; setLastSync: (timestamp: string) => void; + deleteRepository: (repoId: number) => void; // AI actions addAIConfig: (config: AIConfig) => void; @@ -296,6 +297,10 @@ export const useAppStore = create()( }), setLoading: (isLoading) => set({ isLoading }), setLastSync: (lastSync) => set({ lastSync }), + deleteRepository: (repoId) => set((state) => ({ + repositories: state.repositories.filter(r => r.id !== repoId), + searchResults: state.searchResults.filter(r => r.id !== repoId), + })), // AI actions addAIConfig: (config) => set((state) => ({ From 84da7086034a537e17a5f61fba88d20638219b2f Mon Sep 17 00:00:00 2001 From: Clawd Bot Date: Sun, 8 Mar 2026 17:42:10 +0800 Subject: [PATCH 2/2] fix: clean release state on unstar and localize missing-token alert --- src/components/RepositoryCard.tsx | 2 +- src/store/useAppStore.ts | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/components/RepositoryCard.tsx b/src/components/RepositoryCard.tsx index bcf10bc2..6d36545d 100644 --- a/src/components/RepositoryCard.tsx +++ b/src/components/RepositoryCard.tsx @@ -315,7 +315,7 @@ export const RepositoryCard: React.FC = ({ const handleUnstar = async () => { if (!githubToken) { - alert('GitHub token not found. Please login again.'); + alert(t('未找到 GitHub Token,请重新登录。', 'GitHub token not found. Please login again.')); return; } diff --git a/src/store/useAppStore.ts b/src/store/useAppStore.ts index fd2358b0..a8181234 100644 --- a/src/store/useAppStore.ts +++ b/src/store/useAppStore.ts @@ -297,10 +297,24 @@ export const useAppStore = create()( }), setLoading: (isLoading) => set({ isLoading }), setLastSync: (lastSync) => set({ lastSync }), - deleteRepository: (repoId) => set((state) => ({ - repositories: state.repositories.filter(r => r.id !== repoId), - searchResults: state.searchResults.filter(r => r.id !== repoId), - })), + deleteRepository: (repoId) => set((state) => { + const nextReleaseSubscriptions = new Set(state.releaseSubscriptions); + nextReleaseSubscriptions.delete(repoId); + + const filteredReleases = state.releases.filter(release => release.repository.id !== repoId); + const remainingReleaseIds = new Set(filteredReleases.map(release => release.id)); + const nextReadReleases = new Set( + Array.from(state.readReleases).filter(releaseId => remainingReleaseIds.has(releaseId)) + ); + + return { + repositories: state.repositories.filter(r => r.id !== repoId), + searchResults: state.searchResults.filter(r => r.id !== repoId), + releases: filteredReleases, + releaseSubscriptions: nextReleaseSubscriptions, + readReleases: nextReadReleases, + }; + }), // AI actions addAIConfig: (config) => set((state) => ({