优化首页 Gitea Activity 展示
This commit is contained in:
parent
31796260cc
commit
d46f69c9a6
|
|
@ -269,7 +269,7 @@ function mapActivityFeed(
|
|||
const repo = feed.repo?.full_name || fallback.fallbackRepo;
|
||||
const type = normalizeActivityType(feed.op_type);
|
||||
const message =
|
||||
clean(feed.content) ||
|
||||
summarizeActivityMessage(feed.content) ||
|
||||
clean(feed.comment?.body) ||
|
||||
clean(feed.issue?.title) ||
|
||||
clean(feed.pull_request?.title) ||
|
||||
|
|
@ -354,6 +354,28 @@ function clean(value?: string) {
|
|||
return value?.replace(/\s+/g, ' ').trim() || '';
|
||||
}
|
||||
|
||||
function summarizeActivityMessage(value?: string) {
|
||||
const cleaned = clean(value);
|
||||
if (!cleaned.startsWith('{')) {
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(cleaned) as {
|
||||
HeadCommit?: {
|
||||
Message?: string;
|
||||
};
|
||||
Commits?: Array<{
|
||||
Message?: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
return clean(parsed.HeadCommit?.Message) || clean(parsed.Commits?.[0]?.Message) || cleaned;
|
||||
} catch {
|
||||
return cleaned;
|
||||
}
|
||||
}
|
||||
|
||||
function trimTrailingSlash(value: string) {
|
||||
return value.replace(/\/+$/, '');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import type { GiteaActivityData } from '../data/loaders';
|
||||
import { site } from '../config';
|
||||
import { formatDateTime } from '../utils/datetime';
|
||||
import SyncMeta from './SyncMeta.astro';
|
||||
|
||||
interface Props {
|
||||
|
|
@ -26,14 +27,63 @@ const heatmap = Array.from({ length: heatmapSize }, (_, index) => {
|
|||
);
|
||||
});
|
||||
|
||||
const recentActivities = activity.recent.slice(0, 3);
|
||||
function cleanText(value?: string) {
|
||||
return value?.replace(/\s+/g, ' ').trim() || '';
|
||||
}
|
||||
|
||||
function summarizeActivity(item: GiteaActivityData['recent'][number]) {
|
||||
const fallbackMessage = cleanText(item.message) || 'Repository activity';
|
||||
const fallbackTime = item.time;
|
||||
|
||||
if (!fallbackMessage.startsWith('{')) {
|
||||
return {
|
||||
...item,
|
||||
message: fallbackMessage,
|
||||
displayTime: formatDateTime(fallbackTime) || fallbackTime,
|
||||
rawTime: fallbackTime,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(fallbackMessage) as {
|
||||
HeadCommit?: {
|
||||
Message?: string;
|
||||
Timestamp?: string;
|
||||
};
|
||||
Commits?: Array<{
|
||||
Message?: string;
|
||||
Timestamp?: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
const headCommit = parsed.HeadCommit ?? parsed.Commits?.[0];
|
||||
const message = cleanText(headCommit?.Message) || fallbackMessage;
|
||||
const rawTime = headCommit?.Timestamp || fallbackTime;
|
||||
|
||||
return {
|
||||
...item,
|
||||
message,
|
||||
displayTime: formatDateTime(rawTime) || rawTime,
|
||||
rawTime,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
...item,
|
||||
message: fallbackMessage,
|
||||
displayTime: formatDateTime(fallbackTime) || fallbackTime,
|
||||
rawTime: fallbackTime,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const recentActivities = activity.recent.slice(0, 3).map(summarizeActivity);
|
||||
const isPlaceholder = activity.source === 'placeholder';
|
||||
---
|
||||
|
||||
<section class="panel activity-panel">
|
||||
<div class="section-heading" style="margin-bottom: 1rem;">
|
||||
<div>
|
||||
<span class="eyebrow">Gitea Activity</span>
|
||||
<span class="eyebrow activity-panel__eyebrow">Gitea Activity</span>
|
||||
<h2>活跃度概览</h2>
|
||||
<p>
|
||||
{isPlaceholder
|
||||
|
|
@ -84,16 +134,16 @@ const isPlaceholder = activity.source === 'placeholder';
|
|||
recentActivities.length > 0 ? (
|
||||
recentActivities.map((item) => (
|
||||
<article class="activity-item">
|
||||
<strong class="mono">{item.repo}</strong>
|
||||
<p class="activity-item__repo mono">{item.repo}</p>
|
||||
<p class="activity-copy">{item.message}</p>
|
||||
<p class="activity-meta" style="margin-top: 0.55rem;">
|
||||
<span>{item.time}</span>
|
||||
<p class="activity-meta activity-item__meta">
|
||||
<time datetime={item.rawTime}>{item.displayTime}</time>
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
) : (
|
||||
<article class="activity-item">
|
||||
<strong class="mono">暂无同步活动</strong>
|
||||
<p class="activity-item__repo mono">暂无同步活动</p>
|
||||
<p class="activity-copy">先运行一次 content:sync,或等待后续接入真实 Gitea 数据源。</p>
|
||||
</article>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -495,17 +495,22 @@ main {
|
|||
}
|
||||
|
||||
.activity-panel .section-heading p,
|
||||
.activity-panel .section-heading .eyebrow,
|
||||
.activity-panel .activity-copy,
|
||||
.activity-panel .activity-meta,
|
||||
.activity-panel .heatmap-legend {
|
||||
color: rgba(226, 232, 240, 0.86);
|
||||
}
|
||||
|
||||
.activity-panel__eyebrow {
|
||||
border: 1px solid rgba(147, 197, 253, 0.28);
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #eff6ff;
|
||||
}
|
||||
|
||||
.activity-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
gap: 1rem;
|
||||
grid-template-columns: minmax(0, 1.3fr) minmax(18rem, 0.85fr);
|
||||
gap: 1.25rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
|
|
@ -545,19 +550,29 @@ main {
|
|||
.activity-list {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.activity-item {
|
||||
min-width: 0;
|
||||
padding: 0.95rem 1rem;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
border-radius: 1rem;
|
||||
background: rgba(15, 23, 42, 0.32);
|
||||
}
|
||||
|
||||
.activity-item strong {
|
||||
display: block;
|
||||
margin-bottom: 0.25rem;
|
||||
.activity-item__repo {
|
||||
margin: 0 0 0.35rem;
|
||||
color: #fff;
|
||||
font-size: 0.84rem;
|
||||
}
|
||||
|
||||
.activity-panel .activity-copy {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.activity-item__meta {
|
||||
margin-top: 0.55rem;
|
||||
}
|
||||
|
||||
.corner-gallery {
|
||||
|
|
|
|||
Loading…
Reference in New Issue