150 lines
4.4 KiB
TypeScript
150 lines
4.4 KiB
TypeScript
import type { AuthStateValue } from "../shared/auth-messages";
|
||
import type { UpdateManifest } from "../shared/update-check";
|
||
|
||
export function renderLoggedOut(root: HTMLElement, error?: string | null): void {
|
||
root.innerHTML = `
|
||
<section data-popup-state="logged-out">
|
||
<h1>Star Chart Search Enhancer</h1>
|
||
<p>登录后才能使用星图增强功能</p>
|
||
${error ? `<p data-popup-error="true">${error}</p>` : ""}
|
||
<button type="button" data-popup-sign-in="button">登录 Logto</button>
|
||
</section>
|
||
`;
|
||
}
|
||
|
||
export function renderLoggedIn(
|
||
root: HTMLElement,
|
||
authState: AuthStateValue
|
||
): void {
|
||
const userInfo = authState.userInfo;
|
||
|
||
root.innerHTML = `
|
||
<section data-popup-state="logged-in">
|
||
<h1>Star Chart Search Enhancer</h1>
|
||
<p>已登录</p>
|
||
<p>${userInfo?.name ?? userInfo?.username ?? "未知用户"}</p>
|
||
<p>${userInfo?.email ?? ""}</p>
|
||
<section data-popup-update="root">
|
||
<h2>版本更新</h2>
|
||
<p data-popup-update-status="text">正在检查更新...</p>
|
||
</section>
|
||
<button type="button" data-popup-sign-out="button">退出登录</button>
|
||
</section>
|
||
`;
|
||
}
|
||
|
||
export function renderUpdateStatus(
|
||
root: HTMLElement,
|
||
options: {
|
||
currentVersion: string;
|
||
manifest?: UpdateManifest;
|
||
status: "checking" | "error" | "latest" | "available";
|
||
}
|
||
): void {
|
||
const container = root.querySelector('[data-popup-update="root"]');
|
||
if (!container) {
|
||
return;
|
||
}
|
||
|
||
if (options.status === "checking") {
|
||
container.innerHTML = `
|
||
<h2>版本更新</h2>
|
||
<p data-popup-update-status="text">当前版本:${options.currentVersion}</p>
|
||
<p>正在检查更新...</p>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
if (options.status === "error") {
|
||
container.innerHTML = `
|
||
<h2>版本更新</h2>
|
||
<p data-popup-update-status="text">当前版本:${options.currentVersion}</p>
|
||
<p>暂时无法检查更新</p>
|
||
<p>如果需要新版,请联系维护同事获取更新包。</p>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
if (options.status === "latest" || !options.manifest) {
|
||
container.innerHTML = `
|
||
<h2>版本更新</h2>
|
||
<p data-popup-update-status="text">当前版本:${options.currentVersion}</p>
|
||
<p>当前已是最新版本</p>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = `
|
||
<h2>版本更新</h2>
|
||
<p data-popup-update-status="text">当前版本:${options.currentVersion}</p>
|
||
<p>发现新版本:${options.manifest.latestVersion}</p>
|
||
${renderReleaseNotes(options.manifest.releaseNotes)}
|
||
<button type="button" data-popup-download-update="button">下载更新包</button>
|
||
<button type="button" data-popup-download-guide="button">下载使用说明</button>
|
||
<p data-popup-update-download-status="text">下载后请解压新版 zip,并在 chrome://extensions 里重新加载插件。</p>
|
||
`;
|
||
}
|
||
|
||
export function setUpdateDownloadStatus(
|
||
root: HTMLElement,
|
||
value: string
|
||
): void {
|
||
const output = root.querySelector('[data-popup-update-download-status="text"]');
|
||
if (!output) {
|
||
return;
|
||
}
|
||
|
||
output.textContent = value;
|
||
}
|
||
|
||
function renderReleaseNotes(releaseNotes: string[]): string {
|
||
if (releaseNotes.length === 0) {
|
||
return "";
|
||
}
|
||
|
||
return `
|
||
<ul>
|
||
${releaseNotes.map((note) => `<li>${escapeHtml(note)}</li>`).join("")}
|
||
</ul>
|
||
`;
|
||
}
|
||
|
||
function escapeHtml(value: string): string {
|
||
return value
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """);
|
||
}
|
||
|
||
export function renderDevPanel(
|
||
root: HTMLElement,
|
||
authState: AuthStateValue
|
||
): void {
|
||
const panel = root.ownerDocument.createElement("section");
|
||
panel.dataset.popupDevPanel = "root";
|
||
panel.innerHTML = `
|
||
<h2>dev auth panel</h2>
|
||
<p>resource: ${authState.resource ?? ""}</p>
|
||
<p>scopes: ${(authState.scopes ?? []).join(", ")}</p>
|
||
<p>token: ${authState.tokenAvailable ? "available" : "missing"}</p>
|
||
<p>expires: ${authState.accessTokenExpiresAt ?? "unknown"}</p>
|
||
<p>error: ${authState.lastError ?? ""}</p>
|
||
<button type="button" data-popup-test-protected-api="button">测试受保护接口</button>
|
||
<pre data-popup-protected-api-result="output"></pre>
|
||
`;
|
||
root.appendChild(panel);
|
||
}
|
||
|
||
export function setProtectedApiResult(root: HTMLElement, value: string): void {
|
||
const output = root.querySelector(
|
||
'[data-popup-protected-api-result="output"]'
|
||
);
|
||
|
||
if (!output) {
|
||
return;
|
||
}
|
||
|
||
output.textContent = value;
|
||
}
|