ework-web 0.10.106 → 0.10.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/render/layout.ts +5 -0
- package/src/views/issueList.ts +3 -1
- package/src/views/issueThread.ts +27 -2
package/package.json
CHANGED
package/src/render/layout.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface LayoutProps {
|
|
|
26
26
|
extraStatusBadges?: Record<string, { cls: string; label: string }>;
|
|
27
27
|
modelSelect?: { current: string; options: { id: string; label: string }[] } | null;
|
|
28
28
|
runtimeSelect?: { current: string } | null;
|
|
29
|
+
authorLineHtml?: string;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export const THEME_CSS = `
|
|
@@ -163,6 +164,9 @@ header.topbar .num{opacity:.7}
|
|
|
163
164
|
.action-btn.dispatch-btn:hover{background:#6f7781;color:#fff}
|
|
164
165
|
.action-btn.custom-btn{color:var(--accent)}
|
|
165
166
|
.action-btn.custom-btn:hover{background:var(--accent);color:#fff}
|
|
167
|
+
.author-line{color:var(--fg-muted);font-size:.9em;margin:2px 0 6px}
|
|
168
|
+
.author-line .wl-form{display:inline;margin-left:8px}
|
|
169
|
+
.author-line .kind-tag{font-size:.75em;border:1px solid var(--border);border-radius:8px;padding:0 6px;margin-left:4px;color:var(--fg-muted)}
|
|
166
170
|
`;
|
|
167
171
|
|
|
168
172
|
export function renderLayout(props: LayoutProps, inner: string, initialItems: string): string {
|
|
@@ -243,6 +247,7 @@ export function renderLayout(props: LayoutProps, inner: string, initialItems: st
|
|
|
243
247
|
</header>
|
|
244
248
|
<div class="meta-bar">
|
|
245
249
|
<h1>${escapeHtml(props.issueTitle)}</h1>
|
|
250
|
+
${props.authorLineHtml ?? ""}
|
|
246
251
|
<div class="meta-status">
|
|
247
252
|
<span class="state-badge ${stateClass}">${stateLabel}</span>
|
|
248
253
|
${aiBadgeHtml}
|
package/src/views/issueList.ts
CHANGED
|
@@ -25,9 +25,11 @@ function issueRow(
|
|
|
25
25
|
: "";
|
|
26
26
|
const aiBadge = aiStatusBadge(it.ai_status);
|
|
27
27
|
const modelChip = it.model ? ` · <span class="row-model" title="模型">${escapeHtml(it.model)}</span>` : "";
|
|
28
|
+
// Synced issues carry their upstream (GitHub) author; local ones the poster.
|
|
29
|
+
const authorChip = it.author ? ` · <span class="row-author" title="创建者">👤 ${escapeHtml(it.author)}</span>` : "";
|
|
28
30
|
return `<a class="row" href="${escapeAttr(href)}">
|
|
29
31
|
<div class="row-title">${title}${chips}</div>
|
|
30
|
-
<div class="row-meta">#${it.number} · 💬 ${it.comment_count} · ${relTime(it.updated_at)}${aiBadge ? ` · ${aiBadge}` : ""}${modelChip}</div>
|
|
32
|
+
<div class="row-meta">#${it.number}${authorChip} · 💬 ${it.comment_count} · ${relTime(it.updated_at)}${aiBadge ? ` · ${aiBadge}` : ""}${modelChip}</div>
|
|
31
33
|
</a>`;
|
|
32
34
|
}
|
|
33
35
|
|
package/src/views/issueThread.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Config } from "../config";
|
|
2
|
-
import { classifyActor, renderCommentCard, type CommentView } from "../render/components";
|
|
2
|
+
import { classifyActor, renderCommentCard, relTime, type CommentView } from "../render/components";
|
|
3
3
|
import { renderMarkdown } from "../render/markdown";
|
|
4
|
-
import { renderLayout, escapeHtml } from "../render/layout";
|
|
4
|
+
import { renderLayout, escapeHtml, escapeAttr } from "../render/layout";
|
|
5
5
|
import { runIssueActionsHook, type IssueActionContext, type IssueAction } from "../issue-actions-hook";
|
|
6
6
|
import { hydrateReactions } from "../reactions";
|
|
7
7
|
import {
|
|
@@ -150,6 +150,30 @@ export async function buildIssueThread(
|
|
|
150
150
|
.split(/[\s,]+/).map((s) => s.trim()).filter(Boolean);
|
|
151
151
|
payload.trustedLogins = (await listProjectMembersWithUsers(project.id)).map((m) => m.user_login);
|
|
152
152
|
|
|
153
|
+
// Submitter line: synced upstream issues/PRs carry their real author. The
|
|
154
|
+
// +白名单 form targets the wake-logins route (add+back fields, 303 back).
|
|
155
|
+
const authorUser = await getUserByLogin(issue.author);
|
|
156
|
+
const authorKind = authorUser?.kind ?? "human";
|
|
157
|
+
const trustedList = payload.trustedLogins ?? [];
|
|
158
|
+
const wakeList = payload.wakeLogins ?? [];
|
|
159
|
+
const lowerAuthor = issue.author.toLowerCase();
|
|
160
|
+
const showAuthorWhitelist =
|
|
161
|
+
viewerIsAdmin &&
|
|
162
|
+
authorKind === "human" &&
|
|
163
|
+
!trustedList.some((l) => l.toLowerCase() === lowerAuthor) &&
|
|
164
|
+
!wakeList.some((l) => l.toLowerCase() === lowerAuthor);
|
|
165
|
+
const authorLineHtml =
|
|
166
|
+
`<div class="author-line">由 <strong>${escapeHtml(issue.author)}</strong> 提交` +
|
|
167
|
+
` <span class="when" data-ts="${escapeAttr(issue.created_at)}" title="${escapeAttr(issue.created_at)}">${relTime(issue.created_at)}</span>` +
|
|
168
|
+
(authorKind === "bot" ? ` <span class="kind-tag">bot</span>` : "") +
|
|
169
|
+
(showAuthorWhitelist
|
|
170
|
+
? `<form method="post" action="/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/settings/ai/wake-logins" class="wl-form">` +
|
|
171
|
+
`<input type="hidden" name="back" value="/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issue.number}">` +
|
|
172
|
+
`<input type="hidden" name="add" value="${escapeAttr(issue.author)}">` +
|
|
173
|
+
`<button type="submit" class="wlbtn">+白名单</button></form>`
|
|
174
|
+
: "") +
|
|
175
|
+
`</div>`;
|
|
176
|
+
|
|
153
177
|
let customActions: IssueAction[] = [];
|
|
154
178
|
let extraStatusBadges: Record<string, { cls: string; label: string }> | undefined;
|
|
155
179
|
if (cfg.issueActionsHook && viewerLogin) {
|
|
@@ -194,6 +218,7 @@ export async function buildIssueThread(
|
|
|
194
218
|
? { current: issue.model ?? "", options: (await listCachedModels()).map((m) => ({ id: m.id, label: m.label })) }
|
|
195
219
|
: null,
|
|
196
220
|
runtimeSelect: cfg.writesEnabled !== false ? { current: issue.runtime ?? "" } : null,
|
|
221
|
+
authorLineHtml,
|
|
197
222
|
},
|
|
198
223
|
safeJsonEmbed(payload),
|
|
199
224
|
displayViews.map((v) => renderCommentCard(v, cfg)).join("")
|