This commit is contained in:
33333-33333 2026-06-21 22:29:00 +09:00
commit 0a6148c73f
67 changed files with 2653 additions and 1519 deletions

View file

@ -1,6 +1,7 @@
"use strict";
function bindUI() {
renderToolPalette();
loadLogPushSettings();
syncLogPushControls();
syncAudioControls();
@ -16,7 +17,7 @@ function bindUI() {
const collapsed = card.classList.toggle("collapsed");
toggle.setAttribute("aria-expanded", collapsed ? "false" : "true");
const state = toggle.querySelector(".panel-card-state");
if (state) state.textContent = collapsed ? "展開" : "折り畳み";
if (state) state.textContent = collapsed ? "\u5c55\u958b" : "\u6298\u308a\u7573\u307f";
});
}
ui.colonyChartTabs?.addEventListener("click", (e) => {
@ -33,7 +34,7 @@ function bindUI() {
uiCache.logPushEnabled = Boolean(ui.logPushEnabled.checked);
audio.notify?.();
saveLogPushSettings();
showToast(uiCache.logPushEnabled ? "ログのプッシュ通知をONにしました。" : "ログのプッシュ通知をOFFにしました。");
showToast(uiCache.logPushEnabled ? "\u30ed\u30b0\u306e\u30d7\u30c3\u30b7\u30e5\u901a\u77e5\u3092ON\u306b\u3057\u307e\u3057\u305f\u3002" : "\u30ed\u30b0\u306e\u30d7\u30c3\u30b7\u30e5\u901a\u77e5\u3092OFF\u306b\u3057\u307e\u3057\u305f\u3002");
});
ui.logPushControls?.addEventListener("change", (e) => {
const input = e.target.closest("[data-push-kind]");
@ -170,7 +171,7 @@ function bindUI() {
const on = audio.setEnabled ? audio.setEnabled(ui.soundMasterToggle.checked) : audio.toggle();
if (on) audio.uiClick?.();
syncAudioControls();
showToast(on ? "効果音をONにしました。" : "効果音をOFFにしました。");
showToast(on ? "\u52b9\u679c\u97f3\u3092ON\u306b\u3057\u307e\u3057\u305f\u3002" : "\u52b9\u679c\u97f3\u3092OFF\u306b\u3057\u307e\u3057\u305f\u3002");
});
document.addEventListener("click", (e) => {
if (!ui.soundMenu || ui.soundMenu.contains(e.target)) return;
@ -264,30 +265,22 @@ function bindUI() {
chainScroll(ui.archiveContent);
transferEdgeScroll(ui.log, rightPanel);
const isTouchDevice = () => matchMedia?.("(pointer: coarse)")?.matches || navigator.maxTouchPoints > 0;
const inputModeManager = window.TarinaiInputMode;
const isTouchDevice = () => Boolean(inputModeManager?.snapshot?.().isTouchDevice || matchMedia?.("(pointer: coarse)")?.matches || navigator.maxTouchPoints > 0);
const setMobileInputMode = (mode = "auto") => {
if (!["auto", "camera", "tool", "family"].includes(mode)) mode = "auto";
mode = inputModeManager?.setMode?.(mode) || (["auto", "camera", "tool", "family"].includes(mode) ? mode : "auto");
uiCache.mobileInputMode = mode;
try { localStorage.setItem("tarinai_mobile_input_mode_v1", mode); } catch (_) {}
ui.mobileModeControls?.querySelectorAll("[data-mobile-mode]").forEach(btn => btn.classList.toggle("active", btn.dataset.mobileMode === mode));
document.body.classList.toggle("mobile-mode-camera", mode === "camera");
document.body.classList.toggle("mobile-mode-tool", mode === "tool");
document.body.classList.toggle("mobile-mode-family", mode === "family");
};
const updateTouchMobileUiClass = () => {
const ua = String(navigator.userAgent || "");
const coarse = Boolean(window.matchMedia && window.matchMedia("(pointer: coarse)").matches);
const noHover = Boolean(window.matchMedia && window.matchMedia("(hover: none)").matches);
const touchPoints = Number(navigator.maxTouchPoints || 0);
const w = window.innerWidth || 9999;
const h = window.innerHeight || 9999;
const mobileUa = /Android|iPhone|iPod|Mobile|Silk/i.test(ua);
const compactPhoneViewport = Math.min(w, h) <= 640 && Math.max(w, h) <= 980;
const enabled = Boolean(coarse && noHover && touchPoints > 0 && compactPhoneViewport && mobileUa);
const enabled = Boolean(inputModeManager?.refresh?.().touchFirst);
document.body.classList.toggle("touch-mobile-ui", enabled);
if (ui.mobileModeControls) ui.mobileModeControls.hidden = !enabled;
};
const mobileInputMode = () => uiCache.mobileInputMode || "auto";
const mobileInputMode = () => inputModeManager?.currentMode || uiCache.mobileInputMode || "auto";
updateTouchMobileUiClass();
window.addEventListener("resize", updateTouchMobileUiClass, { passive: true });
window.matchMedia?.("(pointer: coarse)")?.addEventListener?.("change", updateTouchMobileUiClass);
@ -297,7 +290,7 @@ function bindUI() {
if (!btn) return;
audio.uiClick?.();
setMobileInputMode(btn.dataset.mobileMode || "auto");
showToast(`スマホ操作: ${btn.textContent || btn.dataset.mobileMode}`);
showToast(`\u30b9\u30de\u30db\u64cd\u4f5c: ${btn.textContent || btn.dataset.mobileMode}`);
});
const touchPoint = (touches, index = 0) => {
@ -355,6 +348,7 @@ function bindUI() {
if (target.state === "sleep" || target.state === "seek_bed") target.state = "idle";
target.surpriseTimer = Math.max(target.surpriseTimer || 0, 0.18);
} else {
if (target.type === "pushpin" && target.pinState === "lodged" && target.detachPushpin) target.detachPushpin(world, "pinch");
target.dropTimer = 0;
target.dropMax = 0;
target.dropImpactDone = true;
@ -600,6 +594,7 @@ function bindUI() {
if (target.state === "sleep" || target.state === "seek_bed") target.state = "idle";
target.surpriseTimer = Math.max(target.surpriseTimer || 0, 0.18);
} else {
if (target.type === "pushpin" && target.pinState === "lodged" && target.detachPushpin) target.detachPushpin(world, "pinch");
target.dropTimer = 0;
target.dropMax = 0;
target.dropImpactDone = true;