diff --git a/package-lock.json b/package-lock.json index a6ae5375..ba08856c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "github-stars-manager", - "version": "0.5.4", + "version": "0.5.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "github-stars-manager", - "version": "0.5.4", + "version": "0.5.5", "dependencies": { "date-fns": "^3.3.1", "highlight.js": "^11.11.1", diff --git a/src/components/Header.tsx b/src/components/Header.tsx index fff25ced..a2de590c 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -82,6 +82,8 @@ export const Header: React.FC = () => { if (existing) { return { ...newRepo, + has_fetched_releases: existing.has_fetched_releases, + last_release_fetch_time: existing.last_release_fetch_time, ai_summary: existing.ai_summary, ai_tags: existing.ai_tags, ai_platforms: existing.ai_platforms, @@ -99,10 +101,8 @@ export const Header: React.FC = () => { setRepositories(mergedRepositories); - // 3. 获取Release信息 - console.log('Fetching releases...'); - const releases = await githubApi.getMultipleRepositoryReleases(mergedRepositories.slice(0, 20)); - setReleases(releases); + // Note: Release fetching is now handled by the Refresh button in Release Timeline + // Header sync only syncs the starred repos list setLastSync(new Date().toISOString()); console.log('Sync completed successfully'); @@ -367,7 +367,7 @@ export const Header: React.FC = () => { onClick={handleSync} disabled={isLoading} className="p-1 rounded hover:bg-light-surface dark:hover:bg-white/5 transition-colors disabled:opacity-50" - title={t('同步仓库', 'Sync repositories')} + title={t('同步星标仓库列表(不包含Release)', 'Sync starred repos list (excludes Release)')} > diff --git a/src/components/ReleaseTimeline.tsx b/src/components/ReleaseTimeline.tsx index 37cccb4e..d36d9797 100644 --- a/src/components/ReleaseTimeline.tsx +++ b/src/components/ReleaseTimeline.tsx @@ -36,6 +36,8 @@ export const ReleaseTimeline: React.FC = () => { setReleaseSearchQuery, toggleReleaseExpandedRepository, setReleaseIsRefreshing, + includePreRelease, + setIncludePreRelease, } = useAppStore(); const { toast, confirm } = useDialog(); @@ -179,9 +181,12 @@ export const ReleaseTimeline: React.FC = () => { return links; }, []); - const subscribedReleases = useMemo(() => - releases.filter(release => releaseSubscriptions.has(release.repository.id)), - [releases, releaseSubscriptions] + const subscribedReleases = useMemo(() => + releases.filter(release => + releaseSubscriptions.has(release.repository.id) && + (includePreRelease || !release.prerelease) + ), + [releases, releaseSubscriptions, includePreRelease] ); // 预计算每个 release 的下载链接和过滤后的链接 @@ -301,6 +306,7 @@ export const ReleaseTimeline: React.FC = () => { setReleaseIsRefreshing(true); try { const githubApi = new GitHubApiService(githubToken); + // Only fetch releases for repos that are subscribed to releases const subscribedRepos = repositories.filter(repo => releaseSubscriptions.has(repo.id)); if (subscribedRepos.length === 0) { @@ -308,49 +314,50 @@ export const ReleaseTimeline: React.FC = () => { return; } - const allNewReleases: Release[] = []; - - const latestReleaseTime = releases.length > 0 - ? releases.reduce((max, r) => Math.max(max, new Date(r.published_at).getTime()), 0) - : 0; - const sinceTimestamp = latestReleaseTime > 0 ? new Date(latestReleaseTime).toISOString() : undefined; + // Use the new getMultipleRepositoryReleases with options + const { releases: newReleases, failedRepos } = await githubApi.getMultipleRepositoryReleases( + subscribedRepos, + { includePreRelease } + ); + // Update repository sync metadata only for repos that succeeded + const now = new Date().toISOString(); + const failedRepoIds = new Set(failedRepos.map(repo => repo.repoId)); for (const repo of subscribedRepos) { - const [owner, name] = repo.full_name.split('/'); - - const hasExistingReleases = releases.some(r => r.repository.id === repo.id); - - let repoReleases: Release[]; - if (!hasExistingReleases) { - repoReleases = await githubApi.getRepositoryReleases(owner, name, 1, 10); - } else { - repoReleases = await githubApi.getIncrementalRepositoryReleases(owner, name, sinceTimestamp, 10); + if (failedRepoIds.has(repo.id)) { + continue; } - - repoReleases.forEach(release => { - release.repository.id = repo.id; + updateRepository({ + ...repo, + has_fetched_releases: true, + last_release_fetch_time: now, }); - - allNewReleases.push(...repoReleases); - - await new Promise(resolve => setTimeout(resolve, 200)); } + // Filter out existing releases and add new ones const existingIds = new Set(useAppStore.getState().releases.map(r => r.id)); - const actuallyNewCount = allNewReleases.filter(r => !existingIds.has(r.id)).length; + const actuallyNewReleases = newReleases.filter(r => !existingIds.has(r.id)); + const actuallyNewCount = actuallyNewReleases.length; - if (allNewReleases.length > 0) { - addReleases(allNewReleases); + if (actuallyNewReleases.length > 0) { + addReleases(actuallyNewReleases); } - const now = new Date().toISOString(); setLastRefreshTime(now); - const message = language === 'zh' - ? `刷新完成!发现 ${actuallyNewCount} 个新Release。` - : `Refresh completed! Found ${actuallyNewCount} new releases.`; + // Build success message with failed repos info + let message: string; + if (failedRepos.length > 0) { + message = language === 'zh' + ? `刷新完成!发现 ${actuallyNewCount} 个新Release,${failedRepos.length} 个仓库刷新失败。` + : `Refresh completed! Found ${actuallyNewCount} new releases, ${failedRepos.length} repos failed.`; + } else { + message = language === 'zh' + ? `刷新完成!发现 ${actuallyNewCount} 个新Release。` + : `Refresh completed! Found ${actuallyNewCount} new releases.`; + } - toast(message, 'success'); + toast(message, actuallyNewCount > 0 ? 'success' : 'info'); } catch (error) { console.error('Refresh failed:', error); const errorMessage = language === 'zh' @@ -527,19 +534,38 @@ export const ReleaseTimeline: React.FC = () => { }

- {/* 刷新按钮 - 在有订阅仓库时显示 */} + {/* Pre-release toggle + Refresh button */} {subscribedRepoCount > 0 && ( -
+
+ {/* Pre-release toggle */} + + + {/* Refresh button */} {lastRefreshTime && ( -

+

{t('上次刷新:', 'Last refresh:')} {formatDistanceToNow(new Date(lastRefreshTime), { addSuffix: true })}

)} @@ -598,6 +624,24 @@ export const ReleaseTimeline: React.FC = () => { )} + {/* Pre-release toggle */} + + {/* Refresh Button */}