mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-25 01:00:04 +08:00
fixed # 手牌区新增遗物区
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@ import { configureDiagnostics } from "./diagnostics/index.js";
|
|||||||
|
|
||||||
export const type = "extension";
|
export const type = "extension";
|
||||||
export let shuYing = new Object();
|
export let shuYing = new Object();
|
||||||
const shuYingLocalVersion = "2.0.2.3-rc.3";
|
const shuYingLocalVersion = "2.0.2.3-rc.4";
|
||||||
|
|
||||||
shuYing.name = "术樱包";
|
shuYing.name = "术樱包";
|
||||||
shuYing.editable = false;
|
shuYing.editable = false;
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
}
|
}
|
||||||
.mengsan-hand-scroll-shuying {
|
.mengsan-hand-scroll-shuying {
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
left: 0 !important;
|
left: var(--mengsan-relic-space, 0px) !important;
|
||||||
top: 0 !important;
|
top: 0 !important;
|
||||||
bottom: 0 !important;
|
bottom: 0 !important;
|
||||||
width: 100% !important;
|
width: calc(100% - var(--mengsan-relic-space, 0px)) !important;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
export function mountRelicStrip(root, getRelics, open, createIcon,
|
||||||
|
document, window) {
|
||||||
|
const strip = document.createElement("div");
|
||||||
|
strip.className = "mengsan-hand-relics-shuying";
|
||||||
|
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;
|
||||||
|
const cancel = () => {
|
||||||
|
if (timer !== null) window.clearTimeout(timer);
|
||||||
|
pending?.button.classList.remove("is-pressed");
|
||||||
|
timer = null;
|
||||||
|
pending = null;
|
||||||
|
};
|
||||||
|
const stop = event => event.stopPropagation();
|
||||||
|
const down = event => {
|
||||||
|
stop(event);
|
||||||
|
cancel();
|
||||||
|
const button = event.target.closest?.("button");
|
||||||
|
if (!button || !strip.contains(button) || event.button !== 0) return;
|
||||||
|
pending = { button, id: event.pointerId,
|
||||||
|
x: event.clientX, y: event.clientY };
|
||||||
|
button.classList.add("is-pressed");
|
||||||
|
timer = window.setTimeout(() => {
|
||||||
|
const relic = getRelics().find(item => item.id === button.dataset.relicId);
|
||||||
|
cancel();
|
||||||
|
if (!disposed && relic) open(relic);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
const move = event => {
|
||||||
|
if (event.pointerId !== pending?.id) return;
|
||||||
|
if (Math.hypot(event.clientX - pending.x,
|
||||||
|
event.clientY - pending.y) > 8) cancel();
|
||||||
|
};
|
||||||
|
const up = event => {
|
||||||
|
if (event.pointerId === pending?.id) cancel();
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
const context = event => { stop(event); event.preventDefault(); };
|
||||||
|
const listeners = [
|
||||||
|
[strip, "pointerdown", down], [strip, "pointermove", stop],
|
||||||
|
[strip, "pointerup", stop], [strip, "click", click],
|
||||||
|
[strip, "keydown", stop], [strip, "keyup", stop],
|
||||||
|
[strip, "contextmenu", context], [strip, "scroll", cancel],
|
||||||
|
[strip, "wheel", stop], [strip, "touchstart", stop],
|
||||||
|
[strip, "touchmove", stop], [strip, "touchend", stop],
|
||||||
|
[window, "pointermove", move, true],
|
||||||
|
[window, "pointerup", up, true],
|
||||||
|
[window, "pointercancel", up, true], [window, "blur", cancel],
|
||||||
|
];
|
||||||
|
for (const args of listeners) args[0].addEventListener(...args.slice(1));
|
||||||
|
root.appendChild(strip);
|
||||||
|
const refresh = () => {
|
||||||
|
if (disposed) return;
|
||||||
|
const relics = getRelics();
|
||||||
|
const next = JSON.stringify(relics.map(item => [item.id, item.image, item.name]));
|
||||||
|
if (next === signature) return;
|
||||||
|
signature = next;
|
||||||
|
cancel();
|
||||||
|
strip.replaceChildren();
|
||||||
|
strip.hidden = relics.length === 0;
|
||||||
|
root.style.setProperty("--mengsan-relic-space", relics.length ? "88px" : "0px");
|
||||||
|
for (const relic of relics) {
|
||||||
|
const button = document.createElement("button");
|
||||||
|
button.type = "button";
|
||||||
|
button.dataset.relicId = relic.id;
|
||||||
|
button.setAttribute("aria-label", `${relic.name},长按查看描述`);
|
||||||
|
button.setAttribute("aria-haspopup", "dialog");
|
||||||
|
const fallback = document.createElement("span");
|
||||||
|
fallback.textContent = relic.name;
|
||||||
|
const icon = createIcon(relic.image);
|
||||||
|
if (icon) {
|
||||||
|
fallback.hidden = true;
|
||||||
|
icon.addEventListener("error", () => { fallback.hidden = false; },
|
||||||
|
{ once: true });
|
||||||
|
button.appendChild(icon);
|
||||||
|
}
|
||||||
|
button.appendChild(fallback);
|
||||||
|
strip.appendChild(button);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
refresh();
|
||||||
|
return { refresh, dispose() {
|
||||||
|
if (disposed) return;
|
||||||
|
disposed = true;
|
||||||
|
cancel();
|
||||||
|
for (const args of listeners) args[0].removeEventListener(...args.slice(1));
|
||||||
|
strip.remove();
|
||||||
|
const value = root.style.getPropertyValue("--mengsan-relic-space");
|
||||||
|
if (value === "88px" || value === "0px") {
|
||||||
|
if (before) root.style.setProperty("--mengsan-relic-space", before, priority);
|
||||||
|
else root.style.removeProperty("--mengsan-relic-space");
|
||||||
|
}
|
||||||
|
} };
|
||||||
|
}
|
||||||
+15
-7
@@ -1,10 +1,11 @@
|
|||||||
import { ui } from "../../../../noname.js";
|
import { ui } from "../../../../noname.js";
|
||||||
import { heldRelics } from "../relics/definitions.js";
|
import { heldRelics } from "../relics/definitions.js";
|
||||||
import { createRelicIcon } from "./relic-icon.js";
|
import { createRelicIcon } from "./relic-icon.js";
|
||||||
|
import { mountRelicStrip } from "./relic-strip.js";
|
||||||
|
|
||||||
export function mountRelics(session, run, battleRelics) {
|
export function mountRelics(session, run, battleRelics) {
|
||||||
let dialog = null, list = null, previousFocus = null, disposed = false;
|
let dialog = null, list = null, previousFocus = null, disposed = false;
|
||||||
const relics = heldRelics(run);
|
let relics = heldRelics(run), selected = null, strip = null;
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.type = "button";
|
button.type = "button";
|
||||||
button.className = "mengsan-battle-piles-button-shuying " +
|
button.className = "mengsan-battle-piles-button-shuying " +
|
||||||
@@ -21,6 +22,9 @@ export function mountRelics(session, run, battleRelics) {
|
|||||||
if (previousFocus?.isConnected) previousFocus.focus();
|
if (previousFocus?.isConnected) previousFocus.focus();
|
||||||
};
|
};
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
|
relics = heldRelics(run);
|
||||||
|
button.textContent = `遗物 ${relics.length}`;
|
||||||
|
strip?.refresh();
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
list.replaceChildren();
|
list.replaceChildren();
|
||||||
if (!relics.length) {
|
if (!relics.length) {
|
||||||
@@ -28,7 +32,7 @@ export function mountRelics(session, run, battleRelics) {
|
|||||||
empty.textContent = "本次征程尚未获得遗物。";
|
empty.textContent = "本次征程尚未获得遗物。";
|
||||||
list.appendChild(empty);
|
list.appendChild(empty);
|
||||||
}
|
}
|
||||||
for (const relic of relics) {
|
for (const relic of selected ? relics.filter(r => r.id === selected) : relics) {
|
||||||
const row = document.createElement("section");
|
const row = document.createElement("section");
|
||||||
const icon=createRelicIcon(relic.image);if(icon)row.appendChild(icon);
|
const icon=createRelicIcon(relic.image);if(icon)row.appendChild(icon);
|
||||||
const name = document.createElement("h3");
|
const name = document.createElement("h3");
|
||||||
@@ -41,18 +45,19 @@ export function mountRelics(session, run, battleRelics) {
|
|||||||
list.appendChild(row);
|
list.appendChild(row);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
button.addEventListener("click", () => {
|
const open = relic => {
|
||||||
if (disposed || !session.active || dialog) return;
|
if (disposed || !session.active || dialog) return;
|
||||||
|
selected = relic?.id || null;
|
||||||
previousFocus = document.activeElement;
|
previousFocus = document.activeElement;
|
||||||
dialog = document.createElement("dialog");
|
dialog = document.createElement("dialog");
|
||||||
const currentDialog = dialog;
|
const currentDialog = dialog;
|
||||||
dialog.className = "mengsan-deck-dialog-shuying " +
|
dialog.className = "mengsan-deck-dialog-shuying " +
|
||||||
"mengsan-relic-dialog-shuying";
|
"mengsan-relic-dialog-shuying";
|
||||||
dialog.setAttribute("aria-label", "遗物(道具)");
|
dialog.setAttribute("aria-label", relic?.name || "遗物(道具)");
|
||||||
const header = document.createElement("header");
|
const header = document.createElement("header");
|
||||||
header.className = "ms-deck-header";
|
header.className = "ms-deck-header";
|
||||||
const title = document.createElement("h2");
|
const title = document.createElement("h2");
|
||||||
title.textContent = "遗物(道具)";
|
title.textContent = relic?.name || "遗物(道具)";
|
||||||
const dismiss = document.createElement("button");
|
const dismiss = document.createElement("button");
|
||||||
dismiss.type = "button";
|
dismiss.type = "button";
|
||||||
dismiss.className = "ms-deck-button";
|
dismiss.className = "ms-deck-button";
|
||||||
@@ -73,10 +78,13 @@ export function mountRelics(session, run, battleRelics) {
|
|||||||
document.body.appendChild(dialog);
|
document.body.appendChild(dialog);
|
||||||
try { dialog.showModal(); dismiss.focus(); }
|
try { dialog.showModal(); dismiss.focus(); }
|
||||||
catch (error) { close(); throw error; }
|
catch (error) { close(); throw error; }
|
||||||
});
|
};
|
||||||
|
button.addEventListener("click", () => open());
|
||||||
|
if (ui.me) strip = mountRelicStrip(ui.me, () => heldRelics(run),
|
||||||
|
open, createRelicIcon, document, window);
|
||||||
const dispose = () => {
|
const dispose = () => {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
disposed = true; close(); button.remove();
|
disposed = true; close(); strip?.dispose(); button.remove();
|
||||||
};
|
};
|
||||||
session.ownResource(button, dispose);
|
session.ownResource(button, dispose);
|
||||||
return { dispose, refresh };
|
return { dispose, refresh };
|
||||||
|
|||||||
@@ -1376,6 +1376,62 @@ body.mengsan-battle-ui-shuying :is(
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
.mengsan-battle-relics-button-shuying { top: 162px; }
|
.mengsan-battle-relics-button-shuying { top: 162px; }
|
||||||
|
.mengsan-hand-relics-shuying {
|
||||||
|
position: absolute !important;
|
||||||
|
left: 0;
|
||||||
|
bottom: 8px;
|
||||||
|
width: 64px;
|
||||||
|
max-height: calc(100% - 16px);
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
touch-action: pan-y;
|
||||||
|
pointer-events: auto;
|
||||||
|
z-index: 260;
|
||||||
|
background: #234844e6;
|
||||||
|
border-radius: 8px;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #d8ba83 #234844;
|
||||||
|
}
|
||||||
|
.mengsan-hand-relics-shuying[hidden] { display: none; }
|
||||||
|
.mengsan-hand-relics-shuying > button {
|
||||||
|
position: relative !important;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
flex: 0 0 48px;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid #d8ba8380;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #17332f;
|
||||||
|
color: #fff1cb;
|
||||||
|
cursor: pointer;
|
||||||
|
touch-action: pan-y;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
}
|
||||||
|
.mengsan-hand-relics-shuying > button:is(.is-pressed, :focus-visible) {
|
||||||
|
outline: 2px solid #d8ba83;
|
||||||
|
outline-offset: -2px;
|
||||||
|
background: #3b6258;
|
||||||
|
}
|
||||||
|
.mengsan-hand-relics-shuying > button > img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
}
|
||||||
|
.mengsan-hand-relics-shuying > button > span {
|
||||||
|
font: 12px/1.4 "Microsoft YaHei", sans-serif;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
.mengsan-relic-dialog-shuying { max-width: 620px; }
|
.mengsan-relic-dialog-shuying { max-width: 620px; }
|
||||||
.mengsan-relic-list-shuying { overflow-y: auto; padding: 12px 0; }
|
.mengsan-relic-list-shuying { overflow-y: auto; padding: 12px 0; }
|
||||||
.mengsan-relic-list-shuying section {
|
.mengsan-relic-list-shuying section {
|
||||||
|
|||||||
Reference in New Issue
Block a user