mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-29 19:19:59 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd03f876c9 | ||
|
|
d5715c9f5a |
Vendored
+6
-6
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": "2.0.2.3-rc.7",
|
||||
"generated_at": "2026-10-29T06:46:48.548759+00:00",
|
||||
"version": "2.0.2.3-rc.8",
|
||||
"generated_at": "2026-10-29T07:21:47.319980+00:00",
|
||||
"algorithm": "sha256",
|
||||
"update_channels": true,
|
||||
"file_count": 288,
|
||||
"size_bytes": 48048830,
|
||||
"folder_sha256": "54dd60f93ca565bb1f35b7b69a1b0d6bd0171cbe4245dd31d0907f55973b4705",
|
||||
"folder_sha256": "9cc2a7cd12f4b066552c64428dfcf9584a12aaf0e6d1cf1e725c02dbe55582fe",
|
||||
"core": [
|
||||
"extension.js",
|
||||
"menu.js",
|
||||
@@ -439,7 +439,7 @@
|
||||
},
|
||||
"extension.js": {
|
||||
"size": 15731,
|
||||
"sha256": "eeb216122e613bc04b1764ae096920735b6970c3cf5ee9e83fa528e82d62ae29"
|
||||
"sha256": "0a13e40488a5022648ae31334a281a2ad7c439aded37c8743f2ac0746ff65591"
|
||||
},
|
||||
"function.js": {
|
||||
"size": 38588,
|
||||
@@ -1696,7 +1696,7 @@
|
||||
"extension.js": {
|
||||
"type": "file",
|
||||
"size": 15731,
|
||||
"sha256": "eeb216122e613bc04b1764ae096920735b6970c3cf5ee9e83fa528e82d62ae29"
|
||||
"sha256": "0a13e40488a5022648ae31334a281a2ad7c439aded37c8743f2ac0746ff65591"
|
||||
},
|
||||
"function.js": {
|
||||
"type": "file",
|
||||
@@ -3116,7 +3116,7 @@
|
||||
"entry": "mengsan/register.js",
|
||||
"manifest": "dist/modules/mengsan.json",
|
||||
"file_count": 830,
|
||||
"size_bytes": 148049031,
|
||||
"size_bytes": 148053007,
|
||||
"legacy_manifest": "dist/modules/mengsan.legacy.json"
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+32
-32
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": "2.0.2.3-rc.7",
|
||||
"generated_at": "2026-10-29T06:46:48.550770+00:00",
|
||||
"version": "2.0.2.3-rc.8",
|
||||
"generated_at": "2026-10-29T07:21:47.321994+00:00",
|
||||
"algorithm": "sha256",
|
||||
"update_channels": true,
|
||||
"file_count": 830,
|
||||
"size_bytes": 148049031,
|
||||
"folder_sha256": "1695f657990a4f805ada4dfa4799aa88c60af09be675373571c15025028b7644",
|
||||
"size_bytes": 148053007,
|
||||
"folder_sha256": "fe2d3d9cc6b254fe5168e0dd23112a26766277aa969f6ec61ff3243e1c300a51",
|
||||
"core": [
|
||||
"mengsan/register.js"
|
||||
],
|
||||
@@ -4072,8 +4072,8 @@
|
||||
"sha256": "db7b79b425cff1f460f83b6fa38ccff431849acc89b89d34b01017562eeea920"
|
||||
},
|
||||
"mengsan/ui/gm-manager.js": {
|
||||
"size": 9361,
|
||||
"sha256": "6083304040dd8f5f3b46497b250944e5edf94208fca8e94b42f921dd82cf733c"
|
||||
"size": 9913,
|
||||
"sha256": "bdefd7704e499a25e7a02de26c6487dff55c15f2723089c8fd8d85155d9e2afc"
|
||||
},
|
||||
"mengsan/ui/hand/adapter.js": {
|
||||
"size": 935,
|
||||
@@ -4092,20 +4092,20 @@
|
||||
"sha256": "4b804c1d42c6c1171d42a37136fcb903bfb3128beae6a357b52ef9cede54908f"
|
||||
},
|
||||
"mengsan/ui/hand/input.js": {
|
||||
"size": 12452,
|
||||
"sha256": "516b2082be54e9e3f2bd8f5d2cec2f2676817a69c3819528ff3919bcb324650f"
|
||||
"size": 13946,
|
||||
"sha256": "52e18e674a51047a965103d6b708ff52886d9f02d4c3834a54037e31c996aeea"
|
||||
},
|
||||
"mengsan/ui/hand/overlays.js": {
|
||||
"size": 3970,
|
||||
"sha256": "9e489fc939f97a21266764f1beccdda1cc3ac9df22f72c633647d7481fa4e662"
|
||||
},
|
||||
"mengsan/ui/hand/style.css": {
|
||||
"size": 15562,
|
||||
"sha256": "d673f460b44db76148dea6b213f7e0fa5c310ae2d7bcf6b4e86fa9ce3e6f0e05"
|
||||
"size": 15563,
|
||||
"sha256": "0796ae6914b3241a85beebe1db81900e00ae8b997301d6d6a0d379dfcc02951e"
|
||||
},
|
||||
"mengsan/ui/hud/index.js": {
|
||||
"size": 24222,
|
||||
"sha256": "82f446741af2d79e8406ed64dab5b0c432b6f90eeab6e7b7c7331bd6e90ea9b4"
|
||||
"size": 24929,
|
||||
"sha256": "d7932d6f7abb3ee793e63acbdac7774d874a9a96b7034f15579fcdeea78f2111"
|
||||
},
|
||||
"mengsan/ui/hud/overlays.js": {
|
||||
"size": 7007,
|
||||
@@ -4140,12 +4140,12 @@
|
||||
"sha256": "f9d5af85381d23525d8f985635709fd14df234123cd2d04851f0015952e47ab1"
|
||||
},
|
||||
"mengsan/ui/relic-strip.js": {
|
||||
"size": 4035,
|
||||
"sha256": "75993cde0dd7ad76cf064684de87f35f5b174e6105b1ee89c441dd038a3730d9"
|
||||
"size": 4005,
|
||||
"sha256": "85b10f28637618bc52c0521968d8ac674af6c91c88b9d7f622e83753be9aeac8"
|
||||
},
|
||||
"mengsan/ui/relics.js": {
|
||||
"size": 4113,
|
||||
"sha256": "653172b8bde8e96ac79b910de76e03815ae9815ed08ab09445edc3b8f73ce750"
|
||||
"size": 4474,
|
||||
"sha256": "1121847176e229cdf3e682166126c50c37bdbc7ccefebadc6143da1ec63c6f22"
|
||||
},
|
||||
"mengsan/ui/reward-package.js": {
|
||||
"size": 4256,
|
||||
@@ -4156,8 +4156,8 @@
|
||||
"sha256": "c39778c5c256ebb0ea3af19fab34b325d21ab875522162868b4ab2ada34cd12e"
|
||||
},
|
||||
"mengsan/ui/style.css": {
|
||||
"size": 79928,
|
||||
"sha256": "cd291794da3e60569902ff6f09d5a7336f0f4c1edde43ed5ac2d22a1efb762b0"
|
||||
"size": 80819,
|
||||
"sha256": "6823e80898b4595eaeebec5f0127dac837b4b7174bbae22d537e89c81716398c"
|
||||
},
|
||||
"mengsan/ui/virtual-card-grid.js": {
|
||||
"size": 4820,
|
||||
@@ -8346,8 +8346,8 @@
|
||||
},
|
||||
"gm-manager.js": {
|
||||
"type": "file",
|
||||
"size": 9361,
|
||||
"sha256": "6083304040dd8f5f3b46497b250944e5edf94208fca8e94b42f921dd82cf733c"
|
||||
"size": 9913,
|
||||
"sha256": "bdefd7704e499a25e7a02de26c6487dff55c15f2723089c8fd8d85155d9e2afc"
|
||||
},
|
||||
"hand": {
|
||||
"type": "directory",
|
||||
@@ -8374,8 +8374,8 @@
|
||||
},
|
||||
"input.js": {
|
||||
"type": "file",
|
||||
"size": 12452,
|
||||
"sha256": "516b2082be54e9e3f2bd8f5d2cec2f2676817a69c3819528ff3919bcb324650f"
|
||||
"size": 13946,
|
||||
"sha256": "52e18e674a51047a965103d6b708ff52886d9f02d4c3834a54037e31c996aeea"
|
||||
},
|
||||
"overlays.js": {
|
||||
"type": "file",
|
||||
@@ -8384,8 +8384,8 @@
|
||||
},
|
||||
"style.css": {
|
||||
"type": "file",
|
||||
"size": 15562,
|
||||
"sha256": "d673f460b44db76148dea6b213f7e0fa5c310ae2d7bcf6b4e86fa9ce3e6f0e05"
|
||||
"size": 15563,
|
||||
"sha256": "0796ae6914b3241a85beebe1db81900e00ae8b997301d6d6a0d379dfcc02951e"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8394,8 +8394,8 @@
|
||||
"children": {
|
||||
"index.js": {
|
||||
"type": "file",
|
||||
"size": 24222,
|
||||
"sha256": "82f446741af2d79e8406ed64dab5b0c432b6f90eeab6e7b7c7331bd6e90ea9b4"
|
||||
"size": 24929,
|
||||
"sha256": "d7932d6f7abb3ee793e63acbdac7774d874a9a96b7034f15579fcdeea78f2111"
|
||||
},
|
||||
"overlays.js": {
|
||||
"type": "file",
|
||||
@@ -8446,13 +8446,13 @@
|
||||
},
|
||||
"relic-strip.js": {
|
||||
"type": "file",
|
||||
"size": 4035,
|
||||
"sha256": "75993cde0dd7ad76cf064684de87f35f5b174e6105b1ee89c441dd038a3730d9"
|
||||
"size": 4005,
|
||||
"sha256": "85b10f28637618bc52c0521968d8ac674af6c91c88b9d7f622e83753be9aeac8"
|
||||
},
|
||||
"relics.js": {
|
||||
"type": "file",
|
||||
"size": 4113,
|
||||
"sha256": "653172b8bde8e96ac79b910de76e03815ae9815ed08ab09445edc3b8f73ce750"
|
||||
"size": 4474,
|
||||
"sha256": "1121847176e229cdf3e682166126c50c37bdbc7ccefebadc6143da1ec63c6f22"
|
||||
},
|
||||
"reward-package.js": {
|
||||
"type": "file",
|
||||
@@ -8466,8 +8466,8 @@
|
||||
},
|
||||
"style.css": {
|
||||
"type": "file",
|
||||
"size": 79928,
|
||||
"sha256": "cd291794da3e60569902ff6f09d5a7336f0f4c1edde43ed5ac2d22a1efb762b0"
|
||||
"size": 80819,
|
||||
"sha256": "6823e80898b4595eaeebec5f0127dac837b4b7174bbae22d537e89c81716398c"
|
||||
},
|
||||
"virtual-card-grid.js": {
|
||||
"type": "file",
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.2.3-rc.7",
|
||||
"version": "2.0.2.3-rc.8",
|
||||
"module_id": "mengsan",
|
||||
"snapshot": "legacy",
|
||||
"files": [
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import { configureDiagnostics } from "./diagnostics/index.js";
|
||||
|
||||
export const type = "extension";
|
||||
export let shuYing = new Object();
|
||||
const shuYingLocalVersion = "2.0.2.3-rc.7";
|
||||
const shuYingLocalVersion = "2.0.2.3-rc.8";
|
||||
|
||||
shuYing.name = "术樱包";
|
||||
shuYing.editable = false;
|
||||
|
||||
@@ -322,12 +322,21 @@ const server = http.createServer((req, res) => {
|
||||
hud.refresh();
|
||||
},prefix);
|
||||
await holdStatus(page,page.getByRole('button',{
|
||||
name:'长按查看全部状态',exact:true}));
|
||||
name:'点击查看全部状态',exact:true}));
|
||||
assert.ok(await page.getByRole('dialog').isVisible(),'overflow states remain available in the details');checks++;
|
||||
await page.getByRole('button',{name:'关闭',exact:true}).click();
|
||||
assert.equal(await page.evaluate(()=>{const s=document.querySelector('.mengsan-hud-center-shuying').getBoundingClientRect(),p=game.me.getBoundingClientRect();return s.bottom<=p.top&&p.top-s.bottom<=13;}),true,'status chips automatically appear just above the portrait');checks++;
|
||||
await page.locator('.mengsan-hud-statuses-shuying button').first().tap();
|
||||
assert.equal(await page.locator('dialog.mengsan-hud-dialog-shuying').count(),0,'short tap does not open status details');checks++;
|
||||
assert.equal(await page.locator('dialog.mengsan-hud-dialog-shuying').count(),1,'short tap opens the status list');checks++;
|
||||
const statusList = await page.locator('.mengsan-hud-detail-body-shuying').evaluate(body => ({
|
||||
rows:body.querySelectorAll('details').length,
|
||||
position:getComputedStyle(body).position,
|
||||
minHeight:Math.min(...[...body.querySelectorAll('summary')].map(row=>row.getBoundingClientRect().height)),
|
||||
height:body.getBoundingClientRect().height,
|
||||
scrollable:body.scrollHeight>body.clientHeight,
|
||||
}));
|
||||
assert.ok(statusList.rows>20&&statusList.position!=='absolute'&&statusList.minHeight>=48&&statusList.height>0&&statusList.scrollable,'status list keeps all entries in normal flow with large tap targets: '+JSON.stringify(statusList));checks++;
|
||||
await page.getByRole('button',{name:'关闭',exact:true}).click();
|
||||
await holdStatus(page,page.locator('.mengsan-hud-statuses-shuying button').first());
|
||||
assert.ok(await page.locator('dialog.mengsan-hud-dialog-shuying').isVisible());checks++;
|
||||
await page.getByRole('button',{name:'关闭',exact:true}).click();
|
||||
|
||||
@@ -8,6 +8,7 @@ import { SLIMED_NAME, createSlimedData } from "../cards/slimed-card.js";
|
||||
import { WOUND_NAME, createWoundData } from "../cards/wound-card.js";
|
||||
import { INFECTION_NAME, createInfectionData } from "../cards/infection-card.js";
|
||||
import { getDiagnostics } from "../../diagnostics/index.js";
|
||||
import { _status } from "../../../../noname.js";
|
||||
|
||||
const statusFactories = {
|
||||
[DAZED_NAME]: createDazedData,
|
||||
@@ -132,7 +133,17 @@ export function mountGMManager(session, owner, piles, battle, resources, game) {
|
||||
diagnostics.info("temporaryCard.added", {
|
||||
cardName: data.name, cardId: id,
|
||||
});
|
||||
try { game.check(); }
|
||||
try {
|
||||
// check() reuses the choices from before directgain.
|
||||
// Invalidate them without clearing the user's selection.
|
||||
const event = _status.event;
|
||||
if (event?.player === owner) {
|
||||
delete event._cardChoice;
|
||||
delete event._targetChoice;
|
||||
delete event._skillChoice;
|
||||
}
|
||||
game.check();
|
||||
}
|
||||
catch (error) {
|
||||
game.log("GM 临时牌已入手,选择状态刷新失败",
|
||||
error.message);
|
||||
|
||||
@@ -69,7 +69,8 @@ export function createHandInput(player, session, adapter, fan, env, refresh, log
|
||||
event.name !== "chooseToUse" || event.player !== player || !event.isMine?.() ||
|
||||
event.skill || event.complexSelect || event.custom?.replace?.card || event.custom?.replace?.target || event.custom?.replace?.confirm ||
|
||||
!env.isActiveCardUse(event, player) || !env.canPayCard?.(player, card) ||
|
||||
ui.selected.cards.length || ui.selected.targets.length || ui.selected.buttons.length ||
|
||||
(ui.selected.cards.length && (ui.selected.cards.length !== 1 || ui.selected.cards[0] !== card)) ||
|
||||
ui.selected.targets.length || ui.selected.buttons.length ||
|
||||
!card.classList.contains("selectable") || card.classList.contains("noclick") ||
|
||||
status.mousedragging || status.dragged || status.paused2) return false;
|
||||
const cards = get.select(event.selectCard);
|
||||
@@ -83,19 +84,22 @@ export function createHandInput(player, session, adapter, fan, env, refresh, log
|
||||
aim.setAttribute("aria-hidden", "true");
|
||||
aim.setAttribute("preserveAspectRatio", "none");
|
||||
const path = document.createElementNS(aim.namespaceURI, "path");
|
||||
aim.appendChild(path); document.body.appendChild(aim);
|
||||
// Keep the SVG in the same zoom/transform space as the real hand.
|
||||
// Android WebView can paint a body-fixed SVG in a different viewport.
|
||||
aim.appendChild(path); ui.arena.appendChild(aim);
|
||||
}
|
||||
const rect = card.getBoundingClientRect();
|
||||
const x = rect.left + rect.width / 2, y = rect.top + 12;
|
||||
aim.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`);
|
||||
const width = ui.arena.clientWidth, height = ui.arena.clientHeight;
|
||||
aim.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
||||
// Use painted bounds instead of relying on WebView CTM handling of zoom.
|
||||
// With preserveAspectRatio=none, viewport-to-viewBox scaling is linear.
|
||||
const bounds = aim.getBoundingClientRect();
|
||||
if (!(bounds.width > 0 && bounds.height > 0)) {
|
||||
removeAim(); return;
|
||||
}
|
||||
const scaleX = window.innerWidth / bounds.width;
|
||||
const scaleY = window.innerHeight / bounds.height;
|
||||
const scaleX = width / bounds.width;
|
||||
const scaleY = height / bounds.height;
|
||||
const start = { x: (x - bounds.left) * scaleX,
|
||||
y: (y - bounds.top) * scaleY };
|
||||
const end = { x: (point.x - bounds.left) * scaleX,
|
||||
@@ -163,7 +167,7 @@ export function createHandInput(player, session, adapter, fan, env, refresh, log
|
||||
if (!state.moved && Math.hypot(point.x - state.x, point.y - state.y) < 9) return;
|
||||
if (!state.moved) {
|
||||
state.moved = true;
|
||||
engineCall(() => ui.click.card.call(state.card));
|
||||
if (!ui.selected.cards.includes(state.card)) engineCall(() => ui.click.card.call(state.card));
|
||||
state.selected = ui.selected.cards.includes(state.card);
|
||||
const targets = range(state.event);
|
||||
if (!state.selected || !live(state) || !targets) { cleanup(true); return; }
|
||||
@@ -235,6 +239,28 @@ export function createHandInput(player, session, adapter, fan, env, refresh, log
|
||||
for (const type of ["mousedown", "mousemove", "mouseup", "click", "touchstart", "touchmove", "touchend"]) {
|
||||
listen(window, type, compatibility, { capture: true, passive: false });
|
||||
}
|
||||
} else if (adapter.root && status && get) {
|
||||
// Older Android WebViews expose TouchEvent but no PointerEvent.
|
||||
// Route them through the same selection and drawing code.
|
||||
const touchEvent = (event, touch, type) => ({
|
||||
button: 0, isPrimary: true, pointerId: touch.identifier,
|
||||
target: event.target, clientX: touch.clientX, clientY: touch.clientY,
|
||||
type, preventDefault: () => event.preventDefault(),
|
||||
stopImmediatePropagation: () => event.stopImmediatePropagation(),
|
||||
});
|
||||
const options = { capture: true, passive: false };
|
||||
listen(window, "touchstart", event => {
|
||||
if (event.touches.length !== 1) { cancel(); return; }
|
||||
start(touchEvent(event, event.touches[0], "pointerdown"));
|
||||
}, options);
|
||||
for (const [type, handler] of [["touchmove", move], ["touchend", end], ["touchcancel", end]]) {
|
||||
listen(window, type, event => {
|
||||
const touch = Array.from(event.changedTouches).find(item => item.identifier === gesture?.id);
|
||||
if (touch) handler(touchEvent(event, touch, type === "touchcancel" ? "pointercancel" : type));
|
||||
}, options);
|
||||
}
|
||||
listen(window, "click", compatibility, options);
|
||||
listen(window, "blur", cancel);
|
||||
}
|
||||
listen(adapter.root, "pointerover", hover);
|
||||
listen(adapter.root, "pointerleave", () => { if (!gesture) fan.setHover(null); });
|
||||
|
||||
@@ -77,10 +77,10 @@
|
||||
transform-origin: 50% 50% !important;
|
||||
}
|
||||
.mengsan-hand-aim-shuying {
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
overflow: visible;
|
||||
|
||||
+25
-14
@@ -67,29 +67,40 @@ export function mountBattleHUD(player, battle, env) {
|
||||
};
|
||||
const refreshDetails = () => {
|
||||
if (!dialog || !detailBody) return;
|
||||
const entries = collectCombatStatuses(detailTarget, battle)
|
||||
.filter(entry => detailId === null || entry.id === detailId);
|
||||
const entries = collectCombatStatuses(detailTarget, battle);
|
||||
const signature = JSON.stringify(entries);
|
||||
if (signature === detailSignature) return;
|
||||
const expanded = detailSignature === null ? new Set(detailId ? [detailId] : []) :
|
||||
new Set([...detailBody.querySelectorAll('details[open]')].map(row => row.dataset.statusId));
|
||||
detailSignature = signature; detailBody.replaceChildren();
|
||||
if (detailId && !entries.some(entry => entry.id === detailId)) {
|
||||
create('p', '', detailBody, '该状态已失效。');
|
||||
}
|
||||
for (const entry of entries) {
|
||||
const row = create('section', 'mengsan-hud-detail-row-shuying',
|
||||
const row = create('details', 'mengsan-info-row-shuying',
|
||||
detailBody);
|
||||
create('strong', '', row, `${entry.name}${entry.value == null ? '' : ` ${entry.value}${entry.unit ? ` ${entry.unit}` : ''}`}`);
|
||||
row.dataset.statusId = entry.id;
|
||||
row.open = expanded.has(entry.id);
|
||||
const summary = create('summary', '', row);
|
||||
if (entry.icon) {
|
||||
const icon = create('img', 'mengsan-relic-icon-shuying', summary);
|
||||
icon.src = `${assetBase}/assets/status/${entry.icon}`; icon.alt = '';
|
||||
}
|
||||
create('strong', '', summary, `${entry.name}${entry.value == null ? '' : ` ${entry.value}${entry.unit ? ` ${entry.unit}` : ''}`}`);
|
||||
create('p', '', row, entry.detail);
|
||||
}
|
||||
if (!entries.length) create('p', '', detailBody,
|
||||
detailId === null ? '暂无已登记状态。' : '该状态已失效。');
|
||||
if (!entries.length && !detailId) create('p', '', detailBody, '暂无已登记状态。');
|
||||
};
|
||||
const openDetails = (target, id = null) => {
|
||||
if (disposed || frozen || !battle.session.active) return;
|
||||
closeDialog(); previousFocus = document.activeElement;
|
||||
dialog = create('dialog', 'mengsan-hud-dialog-shuying', document.body);
|
||||
dialog = create('dialog', 'mengsan-hud-dialog-shuying mengsan-deck-dialog-shuying mengsan-relic-dialog-shuying', document.body);
|
||||
const current = dialog;
|
||||
create('h2', '', dialog, `${nameOf(target)} · 当前状态`);
|
||||
const close = create('button', 'mengsan-hud-dialog-close-shuying', dialog, '关闭'); close.addEventListener('click', closeDialog);
|
||||
const header = create('header', 'ms-deck-header', dialog);
|
||||
create('h2', '', header, `${nameOf(target)} · 当前状态`);
|
||||
const close = create('button', 'ms-deck-button', header, '关闭'); close.addEventListener('click', closeDialog);
|
||||
detailTarget = target; detailId = id;
|
||||
detailBody = create('div', 'mengsan-hud-detail-body-shuying', dialog);
|
||||
detailBody = create('div', 'mengsan-hud-detail-body-shuying mengsan-relic-list-shuying', dialog);
|
||||
refreshDetails();
|
||||
// Unknown/native marks retain their engine intro and are never hidden by the HUD.
|
||||
dialog.addEventListener('cancel', event => { event.preventDefault(); closeDialog(); });
|
||||
@@ -149,8 +160,8 @@ export function mountBattleHUD(player, battle, env) {
|
||||
statuses.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
const button = statusButton(event);
|
||||
// Pointer clicks require a hold; keyboard activation stays accessible.
|
||||
if (button && event.detail === 0) {
|
||||
// Every entry opens the whole list; precise long presses are optional.
|
||||
if (button && !dialog) {
|
||||
openDetails(player, button.dataset.statusId || null);
|
||||
}
|
||||
});
|
||||
@@ -173,7 +184,7 @@ export function mountBattleHUD(player, battle, env) {
|
||||
const button = existing.get(entry.id) ||
|
||||
create('button', 'mengsan-hud-status-shuying', null);
|
||||
button.dataset.statusId = entry.id;
|
||||
button.setAttribute('aria-label', `${entry.name} ${entry.value ?? ''} ${entry.unit},长按查看状态详情`);
|
||||
button.setAttribute('aria-label', `${entry.name} ${entry.value ?? ''} ${entry.unit},点击查看状态列表`);
|
||||
button.setAttribute('aria-haspopup', 'dialog');
|
||||
if (button.dataset.icon !== (entry.icon || '')) {
|
||||
button.dataset.icon = entry.icon || '';
|
||||
@@ -195,7 +206,7 @@ export function mountBattleHUD(player, battle, env) {
|
||||
const more = existing.get(null) || create('button',
|
||||
'mengsan-hud-status-shuying mengsan-hud-status-more-shuying',
|
||||
null);
|
||||
more.setAttribute('aria-label', '长按查看全部状态');
|
||||
more.setAttribute('aria-label', '点击查看全部状态');
|
||||
more.setAttribute('aria-haspopup', 'dialog');
|
||||
wantedButtons.push(more);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ export function mountRelicStrip(root, getRelics, open, createIcon,
|
||||
document, window) {
|
||||
const strip = document.createElement("div");
|
||||
strip.className = "mengsan-hand-relics-shuying";
|
||||
strip.setAttribute("aria-label", "持有遗物,长按查看描述");
|
||||
strip.setAttribute("aria-label", "持有遗物,点击查看列表");
|
||||
const before = root.style.getPropertyValue("--mengsan-relic-space");
|
||||
const priority = root.style.getPropertyPriority("--mengsan-relic-space");
|
||||
let pending = null, timer = null, signature = null, disposed = false;
|
||||
@@ -38,7 +38,6 @@ export function mountRelicStrip(root, getRelics, open, createIcon,
|
||||
const click = event => {
|
||||
stop(event);
|
||||
event.preventDefault();
|
||||
if (event.detail !== 0) return;
|
||||
const button = event.target.closest?.("button");
|
||||
const relic = getRelics().find(item => item.id === button?.dataset.relicId);
|
||||
if (relic) open(relic);
|
||||
@@ -71,7 +70,7 @@ export function mountRelicStrip(root, getRelics, open, createIcon,
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.dataset.relicId = relic.id;
|
||||
button.setAttribute("aria-label", `${relic.name},长按查看描述`);
|
||||
button.setAttribute("aria-label", `${relic.name},点击查看遗物列表`);
|
||||
button.setAttribute("aria-haspopup", "dialog");
|
||||
const fallback = document.createElement("span");
|
||||
fallback.textContent = relic.name;
|
||||
|
||||
+14
-7
@@ -26,22 +26,29 @@ export function mountRelics(session, run, battleRelics, { stripRoot = ui.me } =
|
||||
button.textContent = `遗物 ${relics.length}`;
|
||||
strip?.refresh();
|
||||
if (!list) return;
|
||||
const expanded = new Set([...list.querySelectorAll('details[open]')].map(row => row.dataset.relicId));
|
||||
if (!list.children.length && selected) expanded.add(selected);
|
||||
list.replaceChildren();
|
||||
if (!relics.length) {
|
||||
const empty = document.createElement("p");
|
||||
empty.textContent = "本次征程尚未获得遗物。";
|
||||
list.appendChild(empty);
|
||||
}
|
||||
for (const relic of selected ? relics.filter(r => r.id === selected) : relics) {
|
||||
const row = document.createElement("section");
|
||||
const icon=createRelicIcon(relic.image);if(icon)row.appendChild(icon);
|
||||
const name = document.createElement("h3");
|
||||
for (const relic of relics) {
|
||||
const row = document.createElement("details");
|
||||
row.className = "mengsan-info-row-shuying";
|
||||
row.dataset.relicId = relic.id;
|
||||
row.open = expanded.has(relic.id);
|
||||
const summary = document.createElement("summary");
|
||||
const icon=createRelicIcon(relic.image);if(icon)summary.appendChild(icon);
|
||||
const name = document.createElement("strong");
|
||||
name.textContent = relic.name;
|
||||
summary.appendChild(name);
|
||||
const description = document.createElement("p");
|
||||
description.textContent = relic.description;
|
||||
const status = document.createElement("small");
|
||||
status.textContent = `${relic.pool} · ${relic.tier}${relic.ancient ? ` · ${relic.ancient}` : ""} · ${battleRelics.status(relic)}`;
|
||||
row.append(name, description, status);
|
||||
row.append(summary, description, status);
|
||||
list.appendChild(row);
|
||||
}
|
||||
};
|
||||
@@ -53,11 +60,11 @@ export function mountRelics(session, run, battleRelics, { stripRoot = ui.me } =
|
||||
const currentDialog = dialog;
|
||||
dialog.className = "mengsan-deck-dialog-shuying " +
|
||||
"mengsan-relic-dialog-shuying";
|
||||
dialog.setAttribute("aria-label", relic?.name || "遗物(道具)");
|
||||
dialog.setAttribute("aria-label", "遗物(道具)");
|
||||
const header = document.createElement("header");
|
||||
header.className = "ms-deck-header";
|
||||
const title = document.createElement("h2");
|
||||
title.textContent = relic?.name || "遗物(道具)";
|
||||
title.textContent = "遗物(道具)";
|
||||
const dismiss = document.createElement("button");
|
||||
dismiss.type = "button";
|
||||
dismiss.className = "ms-deck-button";
|
||||
|
||||
@@ -1434,6 +1434,13 @@ body.mengsan-battle-ui-shuying :is(
|
||||
}
|
||||
.mengsan-relic-dialog-shuying { max-width: 620px; }
|
||||
.mengsan-relic-list-shuying { overflow-y: auto; padding: 12px 0; }
|
||||
.mengsan-deck-dialog-shuying .mengsan-relic-list-shuying { position:relative;display:block;flex:1;min-height:0;overscroll-behavior:contain;touch-action:pan-y; }
|
||||
.mengsan-info-row-shuying { display:block;border-bottom:1px solid #b9975d55;padding:8px 0; }
|
||||
.mengsan-info-row-shuying>summary { display:list-item;min-height:48px;padding:8px 10px;cursor:pointer;touch-action:manipulation;color:#ffe0a1;line-height:32px; }
|
||||
.mengsan-info-row-shuying>summary:focus-visible { outline:2px solid #ffe0a1;outline-offset:-2px; }
|
||||
.mengsan-info-row-shuying>summary>.mengsan-relic-icon-shuying { width:32px;height:32px;vertical-align:middle;margin-right:12px; }
|
||||
.mengsan-info-row-shuying>summary>strong { display:inline;vertical-align:middle;overflow-wrap:anywhere; }
|
||||
.mengsan-info-row-shuying>p,.mengsan-info-row-shuying>small { display:block;padding:8px 12px;white-space:pre-line;overflow-wrap:anywhere; }
|
||||
.mengsan-relic-list-shuying section {
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid #b9975d55;
|
||||
|
||||
Reference in New Issue
Block a user