import React from "react";
import {
Extension, extension, settings, defineSave, method,
useExtensionContext,
type SettingsBuilder, type SaveAPI,
} from "@avg-studio/sdk";
import manifest from "../extension.json";
type Entry = { characterId: string; value: number };
type SaveMap = { values: readonly Entry[] };
// 界面层订阅存档字段时,变量真名是 `${manifest.id}.[字段名]`
// manifest.id 是 Studio 创建扩展时生成的(带随机后缀),不能写死
const VAR_VALUES = `${manifest.id}.values`;
@extension({ id: "affection", label: "好感度" })
export class Affection extends Extension {
static settings = settings((s: SettingsBuilder) => ({
title: s.string("面板标题").default("好感度"),
}));
static saveSchema = defineSave({
values: { type: "list", persistence: "slot", default: [] as Entry[] },
});
static add = method({
title: "增加好感度",
schema: {
character: { type: "character", label: "角色", required: true },
amount: { type: "number", label: "增减量", default: 1 },
},
run(_ctx, params) {
const save = this.save as unknown as SaveAPI<SaveMap>;
const list = save.get("values");
const idx = list.findIndex((e) => e.characterId === params.character);
const next = idx >= 0
? list.map((e, i) => i === idx ? { ...e, value: e.value + params.amount } : e)
: [...list, { characterId: params.character, value: params.amount }];
save.set("values", next);
},
});
render() {
return { component: AffectionPanel, props: {} };
}
}
const AffectionPanel: React.FC = () => {
const ctx = useExtensionContext();
const [title] = ctx.settings.useValue<string>("title");
const [raw] = ctx.variables.useValue(VAR_VALUES);
const entries = (raw as unknown as readonly Entry[] | undefined) ?? [];
return (
<div style={{
position: "absolute", top: "50%", left: "50%",
transform: "translate(-50%, -50%)",
padding: "24px 36px", borderRadius: 12,
background: "rgba(20, 20, 30, 0.92)", color: "white",
fontFamily: "sans-serif", minWidth: 260,
}}>
<h2 style={{ textAlign: "center", margin: 0 }}>{title}</h2>
<ul style={{ listStyle: "none", padding: 0, margin: "20px 0" }}>
{entries.map((e) => {
const ch = ctx.character.get(e.characterId);
return (
<li key={e.characterId} style={{ display: "flex", justifyContent: "space-between", padding: "4px 0" }}>
<span>{ch?.name ?? e.characterId}</span>
<span>💗 {e.value}</span>
</li>
);
})}
{entries.length === 0 && (
<li style={{ textAlign: "center", opacity: 0.5 }}>还没有任何记录</li>
)}
</ul>
<div style={{ textAlign: "center" }}>
<button onClick={() => ctx.ui.hide("affection")}>关闭</button>
</div>
</div>
);
};