Compare commits

...

2 Commits

Author SHA1 Message Date
Hermes
fd56e14fc8 Fix ToolApp edge back touch interception 2026-05-22 07:54:19 +08:00
Hermes
557950f692 Fix ToolApp back preview snapshots 2026-05-22 06:54:34 +08:00
5 changed files with 210 additions and 126 deletions

View File

@@ -102,7 +102,7 @@ var ConfigValidator = {
CLICK_SLOP_DP: { type: "int", min: 2, max: 20, default: 6 },
TOOLAPP_BACK_EDGE_WIDTH_DP: { type: "int", min: 1, max: 120, default: 24 },
ENABLE_TOOLAPP_INNER_BACK_STRIPS: { type: "bool", default: false },
ENABLE_TOOLAPP_SCREEN_BACK_STRIPS: { type: "bool", default: true },
ENABLE_TOOLAPP_SCREEN_BACK_STRIPS: { type: "bool", default: false },
TOOLAPP_BACK_COMMIT_DISTANCE_DP: { type: "int", min: 1, max: 480, default: 72 },
TOOLAPP_BACK_PROGRESS_DISTANCE_DP: { type: "int", min: 1, max: 720, default: 180 },
@@ -738,7 +738,7 @@ var ConfigManager = {
CLICK_SLOP_DP: 6,
TOOLAPP_BACK_EDGE_WIDTH_DP: 24,
ENABLE_TOOLAPP_INNER_BACK_STRIPS: false,
ENABLE_TOOLAPP_SCREEN_BACK_STRIPS: true,
ENABLE_TOOLAPP_SCREEN_BACK_STRIPS: false,
TOOLAPP_BACK_COMMIT_DISTANCE_DP: 72,
TOOLAPP_BACK_PROGRESS_DISTANCE_DP: 180,
ENABLE_BOUNCE: true,
@@ -850,9 +850,9 @@ var ConfigManager = {
{ type: "section", name: "触摸与手势" },
{ key: "CLICK_SLOP_DP", name: "点击位移阈值(dp)", type: "int", min: 1, max: 40, step: 1 },
{ key: "TOOLAPP_BACK_EDGE_WIDTH_DP", name: "返回热区宽度", type: "int", min: 1, max: 120, step: 1 },
{ key: "ENABLE_TOOLAPP_INNER_BACK_STRIPS", name: "启用页面内左右滑动返回", type: "bool" },
{ key: "ENABLE_TOOLAPP_SCREEN_BACK_STRIPS", name: "启用屏幕边缘返回热区(排查用)", type: "bool" },
{ key: "TOOLAPP_BACK_EDGE_WIDTH_DP", name: "返回起手边缘宽度", type: "int", min: 1, max: 120, step: 1 },
{ key: "ENABLE_TOOLAPP_INNER_BACK_STRIPS", name: "启用旧版页面覆盖热区(不推荐)", type: "bool" },
{ key: "ENABLE_TOOLAPP_SCREEN_BACK_STRIPS", name: "启用旧版屏幕覆盖热区(已禁用)", type: "bool" },
{ key: "TOOLAPP_BACK_COMMIT_DISTANCE_DP", name: "设置页返回触发距离", type: "int", min: 1, max: 480, step: 1 },
{ key: "TOOLAPP_BACK_PROGRESS_DISTANCE_DP", name: "设置页返回动画距离", type: "int", min: 1, max: 720, step: 1 },
{ key: "ENABLE_LONG_PRESS", name: "启用长按", type: "bool" },

View File

@@ -322,9 +322,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
if (k === "TOOLAPP_BACK_EDGE_WIDTH_DP" || k === "ENABLE_TOOLAPP_INNER_BACK_STRIPS") {
try {
if (this.state.toolAppActive) {
if (k === "TOOLAPP_BACK_EDGE_WIDTH_DP" && this.updateToolAppInnerBackEdgeWidth) {
this.updateToolAppInnerBackEdgeWidth();
} else if (this.showToolApp) {
if (k === "ENABLE_TOOLAPP_INNER_BACK_STRIPS" && this.showToolApp) {
this.showToolApp(this.state.toolAppRoute || "settings", false);
}
if (this.refreshToolAppScreenBackStrips) this.refreshToolAppScreenBackStrips();

View File

@@ -611,19 +611,83 @@ FloatBallAppWM.prototype.hasToolAppBackTarget = function() {
return false;
};
FloatBallAppWM.prototype.captureToolAppPageSnapshot = function(route) {
var r = this.isToolAppRoute(route) ? String(route) : (this.isToolAppRoute(this.state.toolAppRoute) ? String(this.state.toolAppRoute) : "settings");
var s = this.state || {};
var entry = {
route: r,
settingsGroupKey: (s.settingsGroupKey !== undefined && s.settingsGroupKey !== null) ? String(s.settingsGroupKey) : "",
settingsHomeSelectedItemId: (s.settingsHomeSelectedItemId !== undefined) ? s.settingsHomeSelectedItemId : null,
editingButtonIndex: (s.editingButtonIndex !== undefined) ? s.editingButtonIndex : null,
editingSchemaIndex: (s.editingSchemaIndex !== undefined) ? s.editingSchemaIndex : null,
keepBtnEditorState: !!s.keepBtnEditorState,
keepSchemaEditorState: !!s.keepSchemaEditorState,
toolAppSubRoute: (s.toolAppSubRoute !== undefined) ? s.toolAppSubRoute : null,
toolAppSubPage: (s.toolAppSubPage !== undefined) ? s.toolAppSubPage : null,
toolAppSubKey: (s.toolAppSubKey !== undefined) ? s.toolAppSubKey : null,
toolAppSubPayload: (s.toolAppSubPayload !== undefined) ? s.toolAppSubPayload : null
};
if (r !== "settings_group") entry.settingsGroupKey = "";
if (r !== "settings") entry.settingsHomeSelectedItemId = null;
if (r !== "btn_editor") { entry.editingButtonIndex = null; entry.keepBtnEditorState = false; }
if (r !== "schema_editor") { entry.editingSchemaIndex = null; entry.keepSchemaEditorState = false; }
return entry;
};
FloatBallAppWM.prototype.makeToolAppStackEntry = function(route) {
return this.captureToolAppPageSnapshot(route);
};
FloatBallAppWM.prototype.applyToolAppPageSnapshot = function(entry) {
try {
if (!entry || typeof entry !== "object") return false;
var r = this.isToolAppRoute(entry.route) ? String(entry.route) : "settings";
this.state.toolAppRoute = r;
this.state.settingsGroupKey = (entry.settingsGroupKey !== undefined && entry.settingsGroupKey !== null) ? String(entry.settingsGroupKey) : "";
this.state.settingsHomeSelectedItemId = (entry.settingsHomeSelectedItemId !== undefined) ? entry.settingsHomeSelectedItemId : null;
this.state.editingButtonIndex = (entry.editingButtonIndex !== undefined) ? entry.editingButtonIndex : null;
this.state.editingSchemaIndex = (entry.editingSchemaIndex !== undefined) ? entry.editingSchemaIndex : null;
this.state.keepBtnEditorState = !!entry.keepBtnEditorState;
this.state.keepSchemaEditorState = !!entry.keepSchemaEditorState;
this.state.toolAppSubRoute = (entry.toolAppSubRoute !== undefined) ? entry.toolAppSubRoute : null;
this.state.toolAppSubPage = (entry.toolAppSubPage !== undefined) ? entry.toolAppSubPage : null;
this.state.toolAppSubKey = (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null;
this.state.toolAppSubPayload = (entry.toolAppSubPayload !== undefined) ? entry.toolAppSubPayload : null;
return true;
} catch(e) { safeLog(this.L, 'w', "apply tool app snapshot fail: " + String(e)); }
return false;
};
FloatBallAppWM.prototype.cloneToolAppPageSnapshot = function(entry) {
if (!entry || typeof entry !== "object") return this.makeToolAppStackEntry("settings");
return {
route: String(route || "settings"),
settingsGroupKey: String(this.state.settingsGroupKey || "")
route: this.isToolAppRoute(entry.route) ? String(entry.route) : "settings",
settingsGroupKey: (entry.settingsGroupKey !== undefined && entry.settingsGroupKey !== null) ? String(entry.settingsGroupKey) : "",
settingsHomeSelectedItemId: (entry.settingsHomeSelectedItemId !== undefined) ? entry.settingsHomeSelectedItemId : null,
editingButtonIndex: (entry.editingButtonIndex !== undefined) ? entry.editingButtonIndex : null,
editingSchemaIndex: (entry.editingSchemaIndex !== undefined) ? entry.editingSchemaIndex : null,
keepBtnEditorState: !!entry.keepBtnEditorState,
keepSchemaEditorState: !!entry.keepSchemaEditorState,
toolAppSubRoute: (entry.toolAppSubRoute !== undefined) ? entry.toolAppSubRoute : null,
toolAppSubPage: (entry.toolAppSubPage !== undefined) ? entry.toolAppSubPage : null,
toolAppSubKey: (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null,
toolAppSubPayload: (entry.toolAppSubPayload !== undefined) ? entry.toolAppSubPayload : null
};
};
FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
var self = this;
var oldGroupKey = null;
var hasOldGroupKey = false;
var oldSnap = null;
var r = "settings";
try {
oldSnap = this.captureToolAppPageSnapshot ? this.captureToolAppPageSnapshot(this.state.toolAppRoute || "settings") : null;
if (entry && typeof entry === "object") {
if (this.applyToolAppPageSnapshot) this.applyToolAppPageSnapshot(entry);
r = this.isToolAppRoute(entry.route) ? String(entry.route) : "settings";
} else {
r = this.isToolAppRoute(entry) ? String(entry) : "settings";
if (this.applyToolAppPageSnapshot) this.applyToolAppPageSnapshot(this.makeToolAppStackEntry(r));
}
var spec = null;
try {
spec = this.getToolAppResponsiveSpec ? this.getToolAppResponsiveSpec() : null;
@@ -632,18 +696,6 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
}
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
oldGroupKey = this.state.settingsGroupKey;
hasOldGroupKey = true;
var groupKey = null;
if (entry && typeof entry === "object") {
r = this.isToolAppRoute(entry.route) ? String(entry.route) : "settings";
if (entry.settingsGroupKey !== undefined && entry.settingsGroupKey !== null) groupKey = String(entry.settingsGroupKey);
} else {
r = this.isToolAppRoute(entry) ? String(entry) : "settings";
}
if (r === "settings") this.state.settingsGroupKey = null;
else if (r === "settings_group") this.state.settingsGroupKey = groupKey !== null ? groupKey : String(oldGroupKey || "");
var isDark = this.isDarkTheme();
var C = this.ui.colors;
var T = this.getAnimalIslandTheme();
@@ -722,8 +774,8 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
} catch (e) {
safeLog(this.L, 'w', "build tool app preview body fail route=" + String(r || "") + " err=" + String(e));
} finally {
if (hasOldGroupKey) {
try { this.state.settingsGroupKey = oldGroupKey; } catch (eRestore) {}
if (oldSnap && this.applyToolAppPageSnapshot) {
try { this.applyToolAppPageSnapshot(oldSnap); } catch (eRestore) {}
}
}
return null;
@@ -1087,58 +1139,9 @@ FloatBallAppWM.prototype.isToolAppScreenBackStripsEnabled = function() {
};
FloatBallAppWM.prototype.showToolAppScreenBackStrips = function() {
try {
if (!this.state.wm || !this.state.toolAppActive) return false;
if (!this.hasToolAppBackTarget || !this.hasToolAppBackTarget()) {
this.hideToolAppScreenBackStrips();
return false;
}
this.hideToolAppScreenBackStrips();
var sw = Math.max(1, Number(this.state.screen && this.state.screen.w || 0));
if (sw <= 1) {
try { var ss = this.getScreenSizePx(); sw = ss.w; } catch (eScreen) {}
}
var stripDp = Number(this.config.TOOLAPP_BACK_EDGE_WIDTH_DP || 24);
if (isNaN(stripDp)) stripDp = 24;
if (stripDp < 1) stripDp = 1;
if (stripDp > 120) stripDp = 120;
var stripW = this.dp(stripDp);
var flags = android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
var left = this.createToolAppEdgeBackStrip(0);
var lpL = new android.view.WindowManager.LayoutParams(
stripW,
android.view.WindowManager.LayoutParams.MATCH_PARENT,
android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
flags,
android.graphics.PixelFormat.TRANSLUCENT
);
lpL.gravity = android.view.Gravity.START | android.view.Gravity.TOP;
lpL.x = 0;
lpL.y = 0;
var right = this.createToolAppEdgeBackStrip(1);
var lpR = new android.view.WindowManager.LayoutParams(
stripW,
android.view.WindowManager.LayoutParams.MATCH_PARENT,
android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
flags,
android.graphics.PixelFormat.TRANSLUCENT
);
lpR.gravity = android.view.Gravity.START | android.view.Gravity.TOP;
lpR.x = Math.max(0, sw - stripW);
lpR.y = 0;
this.state.wm.addView(left, lpL);
this.state.wm.addView(right, lpR);
this.state.toolAppScreenBackStrips = [left, right];
return true;
} catch (e) {
this.hideToolAppScreenBackStrips();
safeLog(this.L, 'w', "show tool app screen back strips fail: " + String(e));
}
// 兼容旧配置入口:不再创建覆盖 ToolApp 内容区的 MATCH_PARENT 透明触摸层。
// 主要返回手势已迁移到 ToolApp root 的 onInterceptTouchEvent避免遮挡列表/按钮/SeekBar/Switch。
try { this.hideToolAppScreenBackStrips(); } catch(eHide) {}
return false;
};
@@ -1195,7 +1198,108 @@ FloatBallAppWM.prototype.buildToolAppShell = function(contentView, title, canBac
var shellPad = spec ? spec.shellPadding : this.dp(6);
var outerRadius = spec ? spec.outerRadius : this.dp(26);
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
var root = new android.widget.FrameLayout(context);
var rootDownX = 0;
var rootDownY = 0;
var rootEdge = -1;
var rootBackActive = false;
var rootBackMoved = false;
var root = new JavaAdapter(android.widget.FrameLayout, {
onInterceptTouchEvent: function(ev) {
try {
if (!ev) return false;
var action = ev.getActionMasked();
if (action === android.view.MotionEvent.ACTION_DOWN) {
rootDownX = ev.getX();
rootDownY = ev.getY();
rootBackActive = false;
rootBackMoved = false;
rootEdge = -1;
var canBackNow = !!(self.state && self.state.toolAppActive && self.hasToolAppBackTarget && self.hasToolAppBackTarget());
if (canBackNow) {
var edgeW = self.getToolAppBackEdgeWidthPx ? self.getToolAppBackEdgeWidthPx() : self.dp(24);
var rw = 0;
try { rw = this.getWidth(); } catch(eW) { rw = 0; }
if (rootDownX <= edgeW) rootEdge = 0;
else if (rw > 0 && rootDownX >= rw - edgeW) rootEdge = 1;
}
// DOWN 必须放行给子控件,避免按钮/列表/Switch/SeekBar 被边缘手势抢走。
return false;
}
if (action === android.view.MotionEvent.ACTION_MOVE) {
if (rootEdge < 0) return false;
var dx = ev.getX() - rootDownX;
var dy = ev.getY() - rootDownY;
var adx = Math.abs(dx);
var ady = Math.abs(dy);
var validDir = (rootEdge === 0 && dx > 0) || (rootEdge === 1 && dx < 0);
var slopDp = Number(self.config.CLICK_SLOP_DP || 6) * 2;
if (isNaN(slopDp)) slopDp = 12;
if (slopDp < 12) slopDp = 12;
if (slopDp > 40) slopDp = 40;
var touchSlop = self.dp(slopDp);
if (validDir && adx > touchSlop && adx > ady * 1.2) {
rootBackActive = true;
rootBackMoved = true;
try { self.prepareToolAppBackPreview(rootEdge); } catch(ePrep) { try { safeLog(self.L, 'w', 'root back preview prepare fail: ' + String(ePrep)); } catch(eLogPrep) {} }
try { safeLog(self.L, 'd', 'root edge back intercept edge=' + String(rootEdge) + ' dx=' + String(dx)); } catch(eMoveLog) {}
return true;
}
return false;
}
return false;
} catch(e) {
try { safeLog(self.L, 'w', 'tool app root intercept fail: ' + String(e)); } catch(eLog) {}
}
return false;
},
onTouchEvent: function(ev) {
try {
if (!ev) return false;
var action = ev.getActionMasked();
if (!rootBackActive) return false;
if (action === android.view.MotionEvent.ACTION_MOVE) {
var mx = ev.getX() - rootDownX;
var my = ev.getY() - rootDownY;
var validDir2 = (rootEdge === 0 && mx > 0) || (rootEdge === 1 && mx < 0);
if (validDir2 && Math.abs(mx) > Math.abs(my) * 1.2) {
var triggerDp = Number(self.config.TOOLAPP_BACK_PROGRESS_DISTANCE_DP || 180);
if (isNaN(triggerDp)) triggerDp = 180;
if (triggerDp < 1) triggerDp = 1;
if (triggerDp > 720) triggerDp = 720;
var triggerDistance = self.dp(triggerDp);
var p = Math.min(1, Math.abs(mx) / triggerDistance);
self.applyToolAppBackPreviewProgress(rootEdge, p, Math.abs(mx));
}
return true;
}
if (action === android.view.MotionEvent.ACTION_UP || action === android.view.MotionEvent.ACTION_CANCEL) {
var ux = ev.getX() - rootDownX;
var uy = ev.getY() - rootDownY;
var commitDp = Number(self.config.TOOLAPP_BACK_COMMIT_DISTANCE_DP || 72);
if (isNaN(commitDp)) commitDp = 72;
if (commitDp < 1) commitDp = 1;
if (commitDp > 480) commitDp = 480;
var completeDistance = self.dp(commitDp);
var okDir = (rootEdge === 0 && ux > completeDistance) || (rootEdge === 1 && ux < -completeDistance);
var ok = (action === android.view.MotionEvent.ACTION_UP) && rootBackMoved && okDir && Math.abs(ux) > Math.abs(uy) * 1.2;
var edgeDone = rootEdge;
rootBackActive = false;
rootBackMoved = false;
rootEdge = -1;
self.finishToolAppBackPreview(edgeDone, ok);
return true;
}
return true;
} catch(e2) {
try { self.clearToolAppBackPreview(true); } catch(eClear) {}
try { safeLog(self.L, 'w', 'tool app root back touch fail: ' + String(e2)); } catch(eLog2) {}
}
rootBackActive = false;
rootBackMoved = false;
rootEdge = -1;
return false;
}
}, context);
var body = new android.widget.LinearLayout(context);
body.setOrientation(android.widget.LinearLayout.VERTICAL);
// 外层薄荷容器本身就是整张“岛屿设置”卡片:四角统一圆角,并给底部留出完整收口。
@@ -1261,30 +1365,12 @@ FloatBallAppWM.prototype.buildToolAppShell = function(contentView, title, canBac
hostLp.setMargins((spec && (spec.isExpandedWidth || spec.isWideWidth)) ? this.dp(4) : this.dp(6), 0, (spec && (spec.isExpandedWidth || spec.isWideWidth)) ? this.dp(4) : this.dp(6), (spec && (spec.isExpandedWidth || spec.isWideWidth)) ? this.dp(4) : this.dp(6));
body.addView(host, hostLp);
// 页面内透明返回热区可能覆盖内容区左右边缘的真实按钮/列表项/颜色面板
// 默认关闭页面内热区;默认启用更窄的屏幕边缘热区,更贴近全面屏返回习惯
// 兼容旧设置:不再添加页面内透明返回热区。
// 返回手势由 root.onInterceptTouchEvent 按“边缘起手 + 横向阈值 + 方向正确”延迟拦截,避免覆盖控件
try {
var enableInnerBackStrip = false;
try { enableInnerBackStrip = parseBooleanLike(this.config.ENABLE_TOOLAPP_INNER_BACK_STRIPS); } catch(eCfg) { enableInnerBackStrip = false; }
if (enableInnerBackStrip) {
var stripW = this.getToolAppBackEdgeWidthPx ? this.getToolAppBackEdgeWidthPx() : this.dp(24);
var leftStrip = this.createToolAppEdgeBackStrip(0);
var leftLp = new android.widget.FrameLayout.LayoutParams(stripW, -1);
leftLp.gravity = android.view.Gravity.START | android.view.Gravity.TOP;
leftLp.topMargin = topBarHeight + this.dp(8);
root.addView(leftStrip, leftLp);
var rightStrip = this.createToolAppEdgeBackStrip(1);
var rightLp = new android.widget.FrameLayout.LayoutParams(stripW, -1);
rightLp.gravity = android.view.Gravity.END | android.view.Gravity.TOP;
rightLp.topMargin = topBarHeight + this.dp(8);
root.addView(rightStrip, rightLp);
this.state.toolAppInnerBackLeftStrip = leftStrip;
this.state.toolAppInnerBackRightStrip = rightStrip;
} else {
this.state.toolAppInnerBackLeftStrip = null;
this.state.toolAppInnerBackRightStrip = null;
}
} catch (eStrip) { safeLog(this.L, 'w', "add edge back strip fail: " + String(eStrip)); }
} catch (eStrip) { safeLog(this.L, 'w', "clear edge back strip state fail: " + String(eStrip)); }
this.state.toolAppRoot = root;
this.state.toolAppBody = body;
@@ -1429,8 +1515,6 @@ FloatBallAppWM.prototype.showToolApp = function(route, resetStack) {
}
if (resetStack || !this.state.toolAppNavStack || !this.state.toolAppNavStack.length) {
this.state.toolAppNavStack = [this.makeToolAppStackEntry(r)];
} else {
this.state.toolAppNavStack[this.state.toolAppNavStack.length - 1] = this.makeToolAppStackEntry(r);
}
var raw = this.buildPanelView(r);
@@ -1470,7 +1554,12 @@ FloatBallAppWM.prototype.showToolApp = function(route, resetStack) {
FloatBallAppWM.prototype.pushToolAppPage = function(route) {
if (!this.isToolAppRoute(route)) return;
if (!this.state.toolAppNavStack) this.state.toolAppNavStack = [];
this.state.toolAppNavStack.push(this.makeToolAppStackEntry(route));
if (this.state.toolAppNavStack.length <= 0) {
this.state.toolAppNavStack.push(this.makeToolAppStackEntry(this.state.toolAppRoute || "settings"));
}
var nextEntry = this.makeToolAppStackEntry(route);
this.state.toolAppNavStack.push(nextEntry);
if (this.applyToolAppPageSnapshot) this.applyToolAppPageSnapshot(nextEntry);
this.showToolApp(route, false);
};
@@ -1481,8 +1570,10 @@ FloatBallAppWM.prototype.pushToolAppSettingsGroup = function(groupKey) {
FloatBallAppWM.prototype.replaceToolAppPage = function(route) {
if (!this.isToolAppRoute(route)) return;
if (!this.state.toolAppNavStack || !this.state.toolAppNavStack.length) this.state.toolAppNavStack = [this.makeToolAppStackEntry(route)];
else this.state.toolAppNavStack[this.state.toolAppNavStack.length - 1] = this.makeToolAppStackEntry(route);
var entry = this.makeToolAppStackEntry(route);
if (!this.state.toolAppNavStack || !this.state.toolAppNavStack.length) this.state.toolAppNavStack = [entry];
else this.state.toolAppNavStack[this.state.toolAppNavStack.length - 1] = entry;
if (this.applyToolAppPageSnapshot) this.applyToolAppPageSnapshot(entry);
this.showToolApp(route, false);
};
@@ -1493,27 +1584,22 @@ FloatBallAppWM.prototype.popToolAppPage = function(reason) {
var specBack = this.getSettingsResponsiveSpec ? this.getSettingsResponsiveSpec() : null;
if (curRoute === "settings" && specBack && specBack.useSideBySide && this.state.settingsHomeSelectedItemId) {
this.state.settingsHomeSelectedItemId = null;
if (this.state.toolAppNavStack && this.state.toolAppNavStack.length > 0) {
this.state.toolAppNavStack[this.state.toolAppNavStack.length - 1] = this.makeToolAppStackEntry("settings");
}
this.showToolApp("settings", false);
return true;
}
} catch(ePaneBack) {}
if (curRoute === "btn_editor" && this.state.editingButtonIndex !== null && this.state.editingButtonIndex !== undefined) {
this.state.editingButtonIndex = null;
this.state.keepBtnEditorState = true;
}
if (curRoute === "schema_editor" && this.state.editingSchemaIndex !== null && this.state.editingSchemaIndex !== undefined) {
this.state.editingSchemaIndex = null;
this.state.keepSchemaEditorState = true;
}
if (!this.state.toolAppNavStack || this.state.toolAppNavStack.length <= 1) {
this.closeToolApp();
return true;
}
this.state.toolAppNavStack.pop();
var top = this.state.toolAppNavStack[this.state.toolAppNavStack.length - 1];
var nextRoute = top && top.route ? String(top.route) : "settings";
if (nextRoute === "settings_group") this.state.settingsGroupKey = String((top && top.settingsGroupKey) ? top.settingsGroupKey : (this.state.settingsGroupKey || ""));
else this.state.settingsGroupKey = null;
var target = this.cloneToolAppPageSnapshot ? this.cloneToolAppPageSnapshot(top) : top;
var nextRoute = target && target.route ? String(target.route) : "settings";
if (this.applyToolAppPageSnapshot) this.applyToolAppPageSnapshot(target);
this.showToolApp(nextRoute, false);
return true;
} catch (e) {

View File

@@ -2,8 +2,8 @@
"alg": "SHA256withRSA",
"files": {
"th_01_base.js": {
"sha256": "f8651c6ec22e7d06bb3ef2097ee8909523b149afbf5d8b34f9b5c79d8507598a",
"size": 57150
"sha256": "f228e3fda85ab9946934a9950515556d75df110da88432b339258036b8f3a3e2",
"size": 57166
},
"th_02_core.js": {
"sha256": "3c5c498d200e961d48fc9ca3f885475e770ecb32b83ec6a89d23df3f88aed1c9",
@@ -18,8 +18,8 @@
"size": 42568
},
"th_05_persistence.js": {
"sha256": "59fc504c04f6ea397faee33567a773fca175379cba812c37b8ae8c626bc34002",
"size": 15861
"sha256": "1bec9f5bda8e5ae82f2a42707c59e72f4819fffc200d74ae55f191a76009af9b",
"size": 15754
},
"th_06_icon_parser.js": {
"sha256": "25b95a5df634a7ee359f3ab798e4d3154a71c24016f7b4bf8a658096644b2484",
@@ -58,8 +58,8 @@
"size": 304993
},
"th_15_extra.js": {
"sha256": "5fcd5a8146c6bc68e8adc6660c9b12d1f918d7a5a83e00d745a7e18e34ad6f39",
"size": 112080
"sha256": "fb8349a61771903a8c2a3ca6fee15f8df88af79b684e7b444b35c38bcf354ed5",
"size": 117741
},
"th_16_entry.js": {
"sha256": "6c59d9891cd010647f84c3db93f1cf95c7bbfb758470ea21044bf72eb8ff73d1",
@@ -68,5 +68,5 @@
},
"keyId": "toolhub-targets-2026-rsa3072",
"schema": 2,
"version": 20260521224041
"version": 20260521235402
}

View File

@@ -1 +1 @@
OcvlczPduvM0/xKzxRszzLAAOoXdCJ5vj0tf38jAHCYmPA+w0E2JSHIR3uSdr7tBNS42SeBnoHctm9PL00HyaytJvS/N+QIUo8oe6UWK5kVxx5xfeMqmwScGHV6tt93BVc03SwAKepaQZE0dBOFpsEGADwuoVHUEuwsFgRlc6Wl3UuGhcDVrALXgYlZBLy51fs8DmBHxK5CM26Oi2pLC/mI2VpwqMkx64VmsJtgbtVwQdFmwM2Y7tRUf9bGFkPld2gSvWyAAEk/Zul/6z61DHwCSmk0HIuIUb/yFBRxDtBhgQx50jUtKu6JEHhEMFe/eLkb/lfwXPmNIuoHIF89/t8Rf7k7cd5ZrolqeVR0uYcXlmJ3i8nadasnJn1NJh6YobbnmLOoC1NQm5mw2l8e0Q0B+5HEG2NyfxVHxgh1dIvGll2MroJqzpNMTeUW7adE3UBc/wgTO8s6MBAhs+lNLFikgtMvCEDczwymPOn2wBuRxrUY+Ni1UJveGcbNhmUUH
Ho5g8n2gFgHoMdeo0wpzG4b3ufGTSs7Ht1MbGOGU0h0r/u3QRAJKJTCf1JPmSb6mWCOdM8ZL+LD0u8dfpJd9f4AdIJm+PNHH60YGa6QFEAuzh13eh1wQrd2S/gTSQGMSFqQPKRhdMzuTTBJEgMGK0S3siZP6RPK0hdocs5EpFnAtNd6HZWglcds1FVHMCwYiT1JCffRl+azDDaYlo5JqfdPz6hxfQkw+MEY5hQJ0veSbpuv5wNWRZ1OaPgIdwu7BMnGjbCR8BbYylXBkbB0K2K8FKeLDvuPY9je64xSgN1+dJpV1QTr+52BwxDH53u0L7ZVMYOJwOpdtLNhHNVjKJFJn3vcn2jS0DrX6uP9w/qI9X7Ss2bn8Xf/bkaMj6UpOOB+arkme8P2bM+ziGA/CL2n7SLsicvbUv3eNWRsjwTw9EIUx/sEqo6tr+m88eorZo7C3Idy5gdCtVjSSN3kef1XbHtOQshBZwXYpmFYPtRS0WxqEF7F/desj7k7ztnHv