Compare commits
13 Commits
c62328c419
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd3452af45 | ||
|
|
39e62ddaa0 | ||
|
|
9de9983b50 | ||
|
|
0cc6439619 | ||
|
|
095f7ccb39 | ||
|
|
757a60d15d | ||
|
|
d347bb190c | ||
|
|
27dd07da49 | ||
|
|
a327ba2657 | ||
|
|
aa4ef421fe | ||
|
|
00508c9cde | ||
|
|
407cd2200c | ||
|
|
1d49609131 |
21
ToolHub.js
21
ToolHub.js
@@ -33,16 +33,31 @@ function getTrustedShaPath(relPath) { return getCodeDirPath() + ".trusted_sha_"
|
|||||||
function getTrustedVersionPath() { return getCodeDirPath() + ".trusted_manifest_version"; }
|
function getTrustedVersionPath() { return getCodeDirPath() + ".trusted_manifest_version"; }
|
||||||
|
|
||||||
function writeLog(msg) {
|
function writeLog(msg) {
|
||||||
|
var writer = null;
|
||||||
try {
|
try {
|
||||||
var f = new java.io.File(getLogPath());
|
var f = new java.io.File(getLogPath());
|
||||||
var dir = f.getParentFile();
|
var dir = f.getParentFile();
|
||||||
if (dir && !dir.exists()) dir.mkdirs();
|
if (dir && !dir.exists()) dir.mkdirs();
|
||||||
|
try {
|
||||||
|
var maxBytes = 512 * 1024;
|
||||||
|
if (f.exists() && f.length() > maxBytes) {
|
||||||
|
var bak = new java.io.File(String(f.getAbsolutePath()) + ".bak");
|
||||||
|
try { if (bak.exists()) bak.delete(); } catch (eBak0) {}
|
||||||
|
var moved = false;
|
||||||
|
try { moved = f.renameTo(bak); } catch (eMv) { moved = false; }
|
||||||
|
if (!moved) {
|
||||||
|
try { f.delete(); } catch (eDel) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (eTrim) {}
|
||||||
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
var ts = sdf.format(new java.util.Date());
|
var ts = sdf.format(new java.util.Date());
|
||||||
var writer = new java.io.FileWriter(f, true);
|
writer = new java.io.FileWriter(f, true);
|
||||||
writer.write("[" + ts + "] " + String(msg) + "\n");
|
writer.write("[" + ts + "] " + String(msg) + "\n");
|
||||||
writer.close();
|
} catch (e) {
|
||||||
} catch (e) {}
|
} finally {
|
||||||
|
try { if (writer) writer.close(); } catch (eClose) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function runShell(cmdArr) {
|
function runShell(cmdArr) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
a154dbf74570e6cd8ca14ad212c9213824b9c82d94722e0959e9e51cce577447 ToolHub.js
|
01d93690bdfc402ad59d6f51db45e3e057a3ebcbbf146a5667ecc5486e2d3ed6 ToolHub.js
|
||||||
|
|||||||
@@ -1188,8 +1188,15 @@ function applyRule(rule, kv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =======================【日志:文件写入器(尽力落盘 + 自动清理旧日志)】=======================
|
// =======================【日志:文件写入器(尽力落盘 + 自动清理旧日志)】=======================
|
||||||
// =======================【日志:文件写入器(全局统一目录 + 分级)】=======================
|
function sanitizeLogMessage(msg) {
|
||||||
// 优化后的日志系统(带缓冲,减少文件 IO)
|
try {
|
||||||
|
var s = String(msg == null ? "" : msg);
|
||||||
|
s = s.replace(/(authorization\s*[:=]\s*bearer\s+)[^\s,;]+/ig, "$1[REDACTED]");
|
||||||
|
s = s.replace(/((access_)?token|api[_-]?key|password|passwd|secret)(\s*[=:]\s*)[^\s,;]+/ig, "$1$3[REDACTED]");
|
||||||
|
return s;
|
||||||
|
} catch (e) { return String(msg == null ? "" : msg); }
|
||||||
|
}
|
||||||
|
|
||||||
function ToolHubLogger(procInfo) {
|
function ToolHubLogger(procInfo) {
|
||||||
this.proc = procInfo || {};
|
this.proc = procInfo || {};
|
||||||
this.dir = PATH_LOG_DIR;
|
this.dir = PATH_LOG_DIR;
|
||||||
@@ -1199,17 +1206,10 @@ function ToolHubLogger(procInfo) {
|
|||||||
this.debug = false;
|
this.debug = false;
|
||||||
this.initOk = false;
|
this.initOk = false;
|
||||||
this.lastInitErr = "";
|
this.lastInitErr = "";
|
||||||
|
|
||||||
// 新增:日志缓冲
|
|
||||||
this._buffer = [];
|
|
||||||
this._bufferSize = 20; // 每 20 条写一次磁盘
|
|
||||||
this._flushTimer = null;
|
|
||||||
|
|
||||||
this._initOnce();
|
this._initOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolHubLogger.prototype._now = function() { return new Date().getTime(); };
|
ToolHubLogger.prototype._now = function() { return new Date().getTime(); };
|
||||||
|
|
||||||
ToolHubLogger.prototype._initOnce = function() {
|
ToolHubLogger.prototype._initOnce = function() {
|
||||||
try {
|
try {
|
||||||
if (FileIO.ensureDir(this.dir)) {
|
if (FileIO.ensureDir(this.dir)) {
|
||||||
@@ -1224,110 +1224,22 @@ ToolHubLogger.prototype._initOnce = function() {
|
|||||||
this.lastInitErr = String(e);
|
this.lastInitErr = String(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ToolHubLogger.prototype.updateConfig = function(cfg) {
|
ToolHubLogger.prototype.updateConfig = function(cfg) {
|
||||||
if (!cfg) return;
|
if (!cfg) return;
|
||||||
if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS;
|
if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS;
|
||||||
if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE;
|
if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE;
|
||||||
if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG;
|
if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG;
|
||||||
};
|
};
|
||||||
|
|
||||||
ToolHubLogger.prototype._line = function(level, msg) {
|
|
||||||
var ts = this._now();
|
|
||||||
var d = new Date(ts);
|
|
||||||
function pad2(x) { return (x < 10 ? "0" : "") + x; }
|
|
||||||
var t = d.getFullYear() + "-" + pad2(d.getMonth() + 1) + "-" + pad2(d.getDate()) +
|
|
||||||
" " + pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds());
|
|
||||||
return t + " [" + level + "] " + msg + "\n";
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolHubLogger.prototype._scheduleFlush = function() {
|
|
||||||
if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) {}
|
|
||||||
var self = this;
|
|
||||||
this._flushTimer = new java.util.Timer();
|
|
||||||
this._flushTimer.schedule(new java.util.TimerTask({
|
|
||||||
run: function() { self._flushBuffer(); }
|
|
||||||
}), 3000); // 3秒后强制刷新
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolHubLogger.prototype._flushBuffer = function() {
|
|
||||||
if (this._buffer.length === 0) return;
|
|
||||||
var content = this._buffer.join('');
|
|
||||||
this._buffer = [];
|
|
||||||
var path = this.dir + "/" + this.prefix + "_" + this._ymd() + ".log";
|
|
||||||
FileIO.appendText(path, content);
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolHubLogger.prototype._ymd = function() {
|
ToolHubLogger.prototype._ymd = function() {
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
return "" + d.getFullYear() +
|
return "" + d.getFullYear() +
|
||||||
((d.getMonth() < 9 ? "0" : "") + (d.getMonth() + 1)) +
|
((d.getMonth() < 9 ? "0" : "") + (d.getMonth() + 1)) +
|
||||||
((d.getDate() < 10 ? "0" : "") + d.getDate());
|
((d.getDate() < 10 ? "0" : "") + d.getDate());
|
||||||
};
|
};
|
||||||
|
|
||||||
ToolHubLogger.prototype._write = function(level, msg) {
|
|
||||||
if (!this.enable) return false;
|
|
||||||
this._buffer.push(this._line(level, msg));
|
|
||||||
|
|
||||||
// 缓冲满或错误级别立即写入
|
|
||||||
if (this._buffer.length >= this._bufferSize || level === 'F' || level === 'E') {
|
|
||||||
this._flushBuffer();
|
|
||||||
} else {
|
|
||||||
this._scheduleFlush(); // 延迟写入
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolHubLogger.prototype.d = function(msg) { if (this.debug) this._write("D", msg); };
|
|
||||||
ToolHubLogger.prototype.i = function(msg) { this._write("I", msg); };
|
|
||||||
ToolHubLogger.prototype.w = function(msg) { this._write("W", msg); };
|
|
||||||
ToolHubLogger.prototype.e = function(msg) { this._write("E", msg); };
|
|
||||||
ToolHubLogger.prototype.fatal = function(msg) { this._write("F", msg); this._flushBuffer(); };
|
|
||||||
|
|
||||||
ToolHubLogger.prototype.cleanupOldFiles = function() {
|
|
||||||
try {
|
|
||||||
if (!this.initOk) return false;
|
|
||||||
var dirF = new java.io.File(this.dir);
|
|
||||||
var files = dirF.listFiles();
|
|
||||||
if (!files) return false;
|
|
||||||
var now = this._now();
|
|
||||||
var cutoff = now - this.keepDays * 24 * 60 * 60 * 1000;
|
|
||||||
for (var i = 0; i < files.length; i++) {
|
|
||||||
var f = files[i];
|
|
||||||
if (f && f.isFile() && f.getName().indexOf(this.prefix) === 0 && f.lastModified() < cutoff) {
|
|
||||||
f["delete"]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (e) { return false; };
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolHubLogger.prototype._filePathForToday = function() {
|
ToolHubLogger.prototype._filePathForToday = function() {
|
||||||
var name = this.prefix + "_" + this._ymd(this._now()) + ".log";
|
var name = this.prefix + "_" + this._ymd() + ".log";
|
||||||
return this.dir + "/" + name;
|
return this.dir + "/" + name;
|
||||||
};
|
};
|
||||||
ToolHubLogger.prototype._initOnce = function() {
|
|
||||||
try {
|
|
||||||
// # 尝试创建目录
|
|
||||||
if (FileIO.ensureDir(this.dir)) {
|
|
||||||
this.initOk = true;
|
|
||||||
// # 清理旧日志
|
|
||||||
this.cleanupOldFiles();
|
|
||||||
} else {
|
|
||||||
this.initOk = false;
|
|
||||||
this.lastInitErr = "Mkdirs failed: " + this.dir;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.initOk = false;
|
|
||||||
this.lastInitErr = String(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ToolHubLogger.prototype.updateConfig = function(cfg) {
|
|
||||||
if (!cfg) return;
|
|
||||||
if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS;
|
|
||||||
if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE;
|
|
||||||
if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG;
|
|
||||||
};
|
|
||||||
ToolHubLogger.prototype._line = function(level, msg) {
|
ToolHubLogger.prototype._line = function(level, msg) {
|
||||||
var ts = this._now();
|
var ts = this._now();
|
||||||
var d = new Date(ts);
|
var d = new Date(ts);
|
||||||
@@ -1339,7 +1251,7 @@ ToolHubLogger.prototype._line = function(level, msg) {
|
|||||||
proc = " uid=" + String(this.proc.uid) + " pid=" + String(this.proc.pid) + " tid=" + String(this.proc.tid) +
|
proc = " uid=" + String(this.proc.uid) + " pid=" + String(this.proc.pid) + " tid=" + String(this.proc.tid) +
|
||||||
" th=" + String(this.proc.threadName) + " proc=" + String(this.proc.processName);
|
" th=" + String(this.proc.threadName) + " proc=" + String(this.proc.processName);
|
||||||
} catch (e0) {}
|
} catch (e0) {}
|
||||||
return t + " [" + String(level) + "] " + String(msg) + proc + "\n";
|
return t + " [" + String(level) + "] " + sanitizeLogMessage(msg) + proc + "\n";
|
||||||
};
|
};
|
||||||
ToolHubLogger.prototype._writeRaw = function(level, msg) {
|
ToolHubLogger.prototype._writeRaw = function(level, msg) {
|
||||||
if (!this.initOk) return false;
|
if (!this.initOk) return false;
|
||||||
|
|||||||
@@ -288,7 +288,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
|||||||
try {
|
try {
|
||||||
if (this.L) {
|
if (this.L) {
|
||||||
this.L.enable = !!this.config.LOG_ENABLE;
|
this.L.enable = !!this.config.LOG_ENABLE;
|
||||||
this.L.cfg.LOG_ENABLE = !!this.config.LOG_ENABLE;
|
|
||||||
this.L.i("apply LOG_ENABLE=" + String(this.config.LOG_ENABLE));
|
this.L.i("apply LOG_ENABLE=" + String(this.config.LOG_ENABLE));
|
||||||
}
|
}
|
||||||
} catch(eLE) { safeLog(null, 'e', "catch " + String(eLE)); }
|
} catch(eLE) { safeLog(null, 'e', "catch " + String(eLE)); }
|
||||||
@@ -298,7 +297,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
|||||||
try {
|
try {
|
||||||
if (this.L) {
|
if (this.L) {
|
||||||
this.L.debug = !!this.config.LOG_DEBUG;
|
this.L.debug = !!this.config.LOG_DEBUG;
|
||||||
this.L.cfg.LOG_DEBUG = !!this.config.LOG_DEBUG;
|
|
||||||
this.L.i("apply LOG_DEBUG=" + String(this.config.LOG_DEBUG));
|
this.L.i("apply LOG_DEBUG=" + String(this.config.LOG_DEBUG));
|
||||||
}
|
}
|
||||||
} catch(eLD) { safeLog(null, 'e', "catch " + String(eLD)); }
|
} catch(eLD) { safeLog(null, 'e', "catch " + String(eLD)); }
|
||||||
@@ -310,7 +308,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
|||||||
this.config.LOG_KEEP_DAYS = n;
|
this.config.LOG_KEEP_DAYS = n;
|
||||||
if (this.L) {
|
if (this.L) {
|
||||||
this.L.keepDays = n;
|
this.L.keepDays = n;
|
||||||
this.L.cfg.LOG_KEEP_DAYS = n;
|
|
||||||
this.L.i("apply LOG_KEEP_DAYS=" + String(n));
|
this.L.i("apply LOG_KEEP_DAYS=" + String(n));
|
||||||
this.L.cleanupOldFiles();
|
this.L.cleanupOldFiles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,24 +21,23 @@ FloatBallAppWM.prototype.execButtonAction = function(btn, idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t === "open_viewer") {
|
if (t === "open_viewer") {
|
||||||
var logPath = (this.L && this.L._filePathForToday) ? this.L._filePathForToday() : "";
|
function tailLogText(path, maxLen) {
|
||||||
if (!logPath) logPath = PATH_LOG_DIR + "/ShortX_ToolHub_" + (new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date())) + ".log";
|
var txt = FileIO.readText(path);
|
||||||
|
if (!txt) return "(日志文件不存在或为空: " + path + ")";
|
||||||
var content = FileIO.readText(logPath);
|
txt = String(txt);
|
||||||
if (!content) content = "(日志文件不存在或为空: " + logPath + ")";
|
if (txt.length > maxLen) txt = "[...前略...]\n" + txt.substring(txt.length - maxLen);
|
||||||
|
|
||||||
if (content.length > 30000) {
|
|
||||||
content = "[...前略...]\n" + content.substring(content.length - 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简单的按行倒序,方便查看最新日志
|
|
||||||
try {
|
try {
|
||||||
var lines = content.split("\n");
|
var lines = txt.split("\n");
|
||||||
if (lines.length > 1) {
|
if (lines.length > 1) txt = lines.reverse().join("\n");
|
||||||
content = lines.reverse().join("\n");
|
|
||||||
}
|
|
||||||
} catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); }
|
} catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); }
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
var runLogPath = (this.L && this.L._filePathForToday) ? this.L._filePathForToday() : "";
|
||||||
|
if (!runLogPath) runLogPath = PATH_LOG_DIR + "/ShortX_ToolHub_" + (new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date())) + ".log";
|
||||||
|
var initLogPath = PATH_LOG_DIR + "/init.log";
|
||||||
|
var content = "【启动/更新日志】\n" + tailLogText(initLogPath, 15000) +
|
||||||
|
"\n\n【运行日志】\n" + tailLogText(runLogPath, 15000);
|
||||||
|
if (content.length > 32000) content = content.substring(0, 32000) + "\n[...后略...]";
|
||||||
this.showViewerPanel("今日日志 (倒序)", content);
|
this.showViewerPanel("今日日志 (倒序)", content);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -132,7 +131,7 @@ return;
|
|||||||
if (r && r.ok) return;
|
if (r && r.ok) return;
|
||||||
|
|
||||||
this.toast("shell 广播桥发送失败");
|
this.toast("shell 广播桥发送失败");
|
||||||
safeLog(this.L, 'e', "shell all failed cmd_b64=" + cmdB64 + " ret=" + JSON.stringify(r || {}));
|
safeLog(this.L, 'e', "shell all failed cmd_b64_len=" + String(cmdB64 ? cmdB64.length : 0) + " ret=" + JSON.stringify(r || {}));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,46 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
var isFollowTheme = !currentColor;
|
var isFollowTheme = !currentColor;
|
||||||
var currentBaseRgbHex = extractTintRgbHex(currentColor);
|
var currentBaseRgbHex = extractTintRgbHex(currentColor);
|
||||||
var currentAlphaByte = extractTintAlphaByte(currentColor);
|
var currentAlphaByte = extractTintAlphaByte(currentColor);
|
||||||
|
var alphaSeek = null;
|
||||||
|
var alphaValTv = null;
|
||||||
|
var updatePreviewFn = function() {};
|
||||||
|
var updateValueTvFn = function() {};
|
||||||
|
var refreshRecentGridFn = function() {};
|
||||||
|
var refreshCommonGridFn = function() {};
|
||||||
|
var syncRgbSeeksFn = function() {};
|
||||||
|
|
||||||
|
// 操作按钮:对齐设置页/按钮管理页的 chip + 主按钮视觉。
|
||||||
|
function createColorPanelActionButton(label, primary, onClick) {
|
||||||
|
var b = new android.widget.TextView(context);
|
||||||
|
b.setText(label);
|
||||||
|
b.setGravity(android.view.Gravity.CENTER);
|
||||||
|
b.setSingleLine(true);
|
||||||
|
b.setTypeface(null, android.graphics.Typeface.BOLD);
|
||||||
|
try { b.setIncludeFontPadding(false); } catch(eFontPad) {}
|
||||||
|
if (primary) {
|
||||||
|
b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15);
|
||||||
|
b.setTextColor(android.graphics.Color.WHITE);
|
||||||
|
b.setPadding(self.dp(18), 0, self.dp(18), 0);
|
||||||
|
try { b.setMinHeight(self.dp(52)); } catch(eMinH1) {}
|
||||||
|
try { b.setBackground(self.ui.createStrokeDrawable(T.primaryDeep, self.withAlpha(T.brown || T.primaryDeep, isDark ? 0.28 : 0.18), self.dp(1), self.dp(26))); } catch(eBg1) {}
|
||||||
|
try { b.setElevation(self.dp(1)); } catch(eElev) {}
|
||||||
|
} else {
|
||||||
|
b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15);
|
||||||
|
b.setTextColor(T.brown || T.sub);
|
||||||
|
b.setPadding(self.dp(16), 0, self.dp(16), 0);
|
||||||
|
try { b.setMinHeight(self.dp(52)); } catch(eMinH2) {}
|
||||||
|
try { b.setBackground(self.ui.createStrokeDrawable(T.card2 || T.card, self.withAlpha(T.stroke || T.brown, isDark ? 0.42 : 0.55), self.dp(1), self.dp(26))); } catch(eBg2) {}
|
||||||
|
try { b.setElevation(self.dp(1)); } catch(eElev2) {}
|
||||||
|
}
|
||||||
|
try { b.setClickable(true); b.setFocusable(true); } catch(eClickable) {}
|
||||||
|
b.setOnClickListener(new android.view.View.OnClickListener({
|
||||||
|
onClick: function(v) {
|
||||||
|
self.touchActivity();
|
||||||
|
try { if (onClick) onClick(v); } catch(eBtn) { safeLog(self.L, 'e', "color panel action err=" + String(eBtn)); }
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
var popupResult = self.showPopupOverlay({
|
var popupResult = self.showPopupOverlay({
|
||||||
title: "换颜色",
|
title: "换颜色",
|
||||||
@@ -156,6 +196,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
}
|
}
|
||||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||||
}
|
}
|
||||||
|
updatePreviewFn = updatePreview;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
|
|
||||||
// ========== 最近使用颜色 ==========
|
// ========== 最近使用颜色 ==========
|
||||||
@@ -239,6 +280,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
}
|
}
|
||||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||||
}
|
}
|
||||||
|
refreshRecentGridFn = refreshRecentGrid;
|
||||||
refreshRecentGrid();
|
refreshRecentGrid();
|
||||||
|
|
||||||
// 21 色常用颜色
|
// 21 色常用颜色
|
||||||
@@ -328,6 +370,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
}
|
}
|
||||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||||
}
|
}
|
||||||
|
refreshCommonGridFn = refreshCommonGrid;
|
||||||
|
|
||||||
// 颜色值显示
|
// 颜色值显示
|
||||||
var valueTv = new android.widget.TextView(context);
|
var valueTv = new android.widget.TextView(context);
|
||||||
@@ -339,6 +382,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
function updateValueTv() {
|
function updateValueTv() {
|
||||||
valueTv.setText(isFollowTheme ? "当前:跟随岛屿主题" : ("当前:" + (selectedColor || "无")));
|
valueTv.setText(isFollowTheme ? "当前:跟随岛屿主题" : ("当前:" + (selectedColor || "无")));
|
||||||
}
|
}
|
||||||
|
updateValueTvFn = updateValueTv;
|
||||||
updateValueTv();
|
updateValueTv();
|
||||||
|
|
||||||
// RGB 滑块
|
// RGB 滑块
|
||||||
@@ -412,6 +456,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
rgbValTvs[2].setText(String(initB));
|
rgbValTvs[2].setText(String(initB));
|
||||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||||
}
|
}
|
||||||
|
syncRgbSeeksFn = syncRgbSeeks;
|
||||||
syncRgbSeeks();
|
syncRgbSeeks();
|
||||||
|
|
||||||
// 透明度滑块
|
// 透明度滑块
|
||||||
@@ -427,14 +472,14 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
alphaLabel.setMinWidth(self.dp(20));
|
alphaLabel.setMinWidth(self.dp(20));
|
||||||
alphaRow.addView(alphaLabel);
|
alphaRow.addView(alphaLabel);
|
||||||
|
|
||||||
var alphaSeek = new android.widget.SeekBar(context);
|
alphaSeek = new android.widget.SeekBar(context);
|
||||||
alphaSeek.setMax(255);
|
alphaSeek.setMax(255);
|
||||||
var alphaSeekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
var alphaSeekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
||||||
alphaSeekLp.setMargins(self.dp(8), 0, self.dp(8), 0);
|
alphaSeekLp.setMargins(self.dp(8), 0, self.dp(8), 0);
|
||||||
alphaSeek.setLayoutParams(alphaSeekLp);
|
alphaSeek.setLayoutParams(alphaSeekLp);
|
||||||
alphaRow.addView(alphaSeek);
|
alphaRow.addView(alphaSeek);
|
||||||
|
|
||||||
var alphaValTv = new android.widget.TextView(context);
|
alphaValTv = new android.widget.TextView(context);
|
||||||
alphaValTv.setTextColor(subTextColor);
|
alphaValTv.setTextColor(subTextColor);
|
||||||
alphaValTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11);
|
alphaValTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11);
|
||||||
alphaValTv.setMinWidth(self.dp(28));
|
alphaValTv.setMinWidth(self.dp(28));
|
||||||
@@ -460,59 +505,25 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
alphaValTv.setText(String(currentAlphaByte));
|
alphaValTv.setText(String(currentAlphaByte));
|
||||||
content.addView(alphaRow);
|
content.addView(alphaRow);
|
||||||
|
|
||||||
// 操作按钮:对齐设置页/按钮管理页的 chip + 主按钮视觉。
|
// 底部操作按钮放到 showPopupOverlay 的固定 footer 中,避免默认首屏看不到。
|
||||||
function createColorPanelActionButton(label, primary, onClick) {
|
},
|
||||||
var b = new android.widget.TextView(context);
|
footerBuilder: function(footer, closePopup) {
|
||||||
b.setText(label);
|
|
||||||
b.setGravity(android.view.Gravity.CENTER);
|
|
||||||
b.setSingleLine(true);
|
|
||||||
b.setTypeface(null, android.graphics.Typeface.BOLD);
|
|
||||||
try { b.setIncludeFontPadding(false); } catch(eFontPad) {}
|
|
||||||
if (primary) {
|
|
||||||
// 与设置页底部“保存布置”一致:主色胶囊、44dp 高、轻描边。
|
|
||||||
b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15);
|
|
||||||
// 颜色面板里不用高饱和青色,改成更沉稳的深绿主按钮。
|
|
||||||
b.setTextColor(android.graphics.Color.WHITE);
|
|
||||||
b.setPadding(self.dp(18), 0, self.dp(18), 0);
|
|
||||||
try { b.setMinHeight(self.dp(52)); } catch(eMinH1) {}
|
|
||||||
try { b.setBackground(self.ui.createStrokeDrawable(T.primaryDeep, self.withAlpha(T.brown || T.primaryDeep, isDark ? 0.28 : 0.18), self.dp(1), self.dp(26))); } catch(eBg1) {}
|
|
||||||
try { b.setElevation(self.dp(1)); } catch(eElev) {}
|
|
||||||
} else {
|
|
||||||
// 与设置页按钮一致:次级也用大圆角按钮,不再做小 chip。
|
|
||||||
b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15);
|
|
||||||
// 次级按钮走设置页里的奶油/描边感,不再用薄荷绿底。
|
|
||||||
b.setTextColor(T.brown || T.sub);
|
|
||||||
b.setPadding(self.dp(16), 0, self.dp(16), 0);
|
|
||||||
try { b.setMinHeight(self.dp(52)); } catch(eMinH2) {}
|
|
||||||
try { b.setBackground(self.ui.createStrokeDrawable(T.card2 || T.card, self.withAlpha(T.stroke || T.brown, isDark ? 0.42 : 0.55), self.dp(1), self.dp(26))); } catch(eBg2) {}
|
|
||||||
try { b.setElevation(self.dp(1)); } catch(eElev2) {}
|
|
||||||
}
|
|
||||||
try { b.setClickable(true); b.setFocusable(true); } catch(eClickable) {}
|
|
||||||
b.setOnClickListener(new android.view.View.OnClickListener({
|
|
||||||
onClick: function(v) {
|
|
||||||
self.touchActivity();
|
|
||||||
try { if (onClick) onClick(v); } catch(eBtn) { safeLog(self.L, 'e', "color panel action err=" + String(eBtn)); }
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
var actionRow = new android.widget.LinearLayout(context);
|
var actionRow = new android.widget.LinearLayout(context);
|
||||||
actionRow.setOrientation(android.widget.LinearLayout.HORIZONTAL);
|
actionRow.setOrientation(android.widget.LinearLayout.HORIZONTAL);
|
||||||
actionRow.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
actionRow.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||||
actionRow.setPadding(self.dp(10), self.dp(10), self.dp(10), self.dp(12));
|
actionRow.setPadding(self.dp(10), self.dp(6), self.dp(10), self.dp(4));
|
||||||
|
|
||||||
var btnClear = createColorPanelActionButton("恢复默认", false, function() {
|
var btnClear = createColorPanelActionButton("恢复默认", false, function() {
|
||||||
isFollowTheme = true;
|
isFollowTheme = true;
|
||||||
selectedColor = "";
|
selectedColor = "";
|
||||||
updatePreview();
|
|
||||||
updateValueTv();
|
|
||||||
refreshRecentGrid();
|
|
||||||
refreshCommonGrid();
|
|
||||||
syncRgbSeeks();
|
|
||||||
alphaSeek.setProgress(255);
|
|
||||||
alphaValTv.setText("255");
|
|
||||||
currentAlphaByte = 255;
|
currentAlphaByte = 255;
|
||||||
|
try { updatePreviewFn(); } catch(eUp) {}
|
||||||
|
try { updateValueTvFn(); } catch(eVal) {}
|
||||||
|
try { refreshRecentGridFn(); } catch(eRecent) {}
|
||||||
|
try { refreshCommonGridFn(); } catch(eCommon) {}
|
||||||
|
try { syncRgbSeeksFn(); } catch(eSync) {}
|
||||||
|
try { if (alphaSeek) alphaSeek.setProgress(255); } catch(eAlphaSeek) {}
|
||||||
|
try { if (alphaValTv) alphaValTv.setText("255"); } catch(eAlphaTv) {}
|
||||||
});
|
});
|
||||||
var clearLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52));
|
var clearLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52));
|
||||||
clearLp.weight = 1;
|
clearLp.weight = 1;
|
||||||
@@ -522,13 +533,9 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
var btnOk = createColorPanelActionButton("保存颜色", true, function() {
|
var btnOk = createColorPanelActionButton("保存颜色", true, function() {
|
||||||
try {
|
try {
|
||||||
var finalColor = isFollowTheme ? "" : String(selectedColor || "");
|
var finalColor = isFollowTheme ? "" : String(selectedColor || "");
|
||||||
if (!isFollowTheme && selectedColor) {
|
if (!isFollowTheme && selectedColor) pushRecentColor(selectedColor);
|
||||||
pushRecentColor(selectedColor);
|
|
||||||
}
|
|
||||||
if (typeof onSelect === "function") {
|
if (typeof onSelect === "function") {
|
||||||
try { onSelect(finalColor); } catch(eOnSelect) {
|
try { onSelect(finalColor); } catch(eOnSelect) { safeLog(self.L, 'e', "colorPicker onSelect err=" + String(eOnSelect)); }
|
||||||
safeLog(self.L, 'e', "colorPicker onSelect err=" + String(eOnSelect));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
safeLog(self.L, 'e', "colorPicker confirm err=" + String(e));
|
safeLog(self.L, 'e', "colorPicker confirm err=" + String(e));
|
||||||
@@ -540,7 +547,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) {
|
|||||||
okLp.setMargins(self.dp(6), 0, 0, 0);
|
okLp.setMargins(self.dp(6), 0, 0, 0);
|
||||||
actionRow.addView(btnOk, okLp);
|
actionRow.addView(btnOk, okLp);
|
||||||
|
|
||||||
content.addView(actionRow, new android.widget.LinearLayout.LayoutParams(
|
footer.addView(actionRow, new android.widget.LinearLayout.LayoutParams(
|
||||||
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
|
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
|
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -4592,6 +4592,7 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
var title = String(opt.title || "");
|
var title = String(opt.title || "");
|
||||||
var onDismiss = (typeof opt.onDismiss === "function") ? opt.onDismiss : null;
|
var onDismiss = (typeof opt.onDismiss === "function") ? opt.onDismiss : null;
|
||||||
var builder = (typeof opt.builder === "function") ? opt.builder : null;
|
var builder = (typeof opt.builder === "function") ? opt.builder : null;
|
||||||
|
var footerBuilder = (typeof opt.footerBuilder === "function") ? opt.footerBuilder : null;
|
||||||
|
|
||||||
var PT = this.getIslandPickerTheme ? this.getIslandPickerTheme() : null;
|
var PT = this.getIslandPickerTheme ? this.getIslandPickerTheme() : null;
|
||||||
var isDark = PT ? PT.isDark : this.isDarkTheme();
|
var isDark = PT ? PT.isDark : this.isDarkTheme();
|
||||||
@@ -4619,12 +4620,168 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
if (panelHeight > sh - self.dp(48)) panelHeight = sh - self.dp(48);
|
if (panelHeight > sh - self.dp(48)) panelHeight = sh - self.dp(48);
|
||||||
if (panelHeight < self.dp(420)) panelHeight = Math.min(sh - self.dp(24), self.dp(420));
|
if (panelHeight < self.dp(420)) panelHeight = Math.min(sh - self.dp(24), self.dp(420));
|
||||||
|
|
||||||
var root = new android.widget.FrameLayout(context);
|
var popupClosed = false;
|
||||||
|
var popupBackDispatcher = null;
|
||||||
|
var popupBackCallback = null;
|
||||||
|
var root = new JavaAdapter(android.widget.FrameLayout, {
|
||||||
|
onWindowFocusChanged: function(hasFocus) {
|
||||||
|
try {
|
||||||
|
android.widget.FrameLayout.prototype.onWindowFocusChanged.call(this, hasFocus);
|
||||||
|
} catch(eSuperFocus) {}
|
||||||
|
try {
|
||||||
|
if (popupClosed) return;
|
||||||
|
// 用户底部上滑回主页 / 进入后台时,overlay 往往会失去焦点;弹窗应自动关闭。
|
||||||
|
if (!hasFocus) this.post(new java.lang.Runnable({ run: function() { closePopup(); } }));
|
||||||
|
} catch(eFocusClose) {}
|
||||||
|
},
|
||||||
|
onWindowVisibilityChanged: function(visibility) {
|
||||||
|
try {
|
||||||
|
android.widget.FrameLayout.prototype.onWindowVisibilityChanged.call(this, visibility);
|
||||||
|
} catch(eSuperVis) {}
|
||||||
|
try {
|
||||||
|
if (popupClosed) return;
|
||||||
|
if (visibility !== android.view.View.VISIBLE) this.post(new java.lang.Runnable({ run: function() { closePopup(); } }));
|
||||||
|
} catch(eVisClose) {}
|
||||||
|
},
|
||||||
|
onDetachedFromWindow: function() {
|
||||||
|
try { popupClosed = true; } catch(eMarkDetached) {}
|
||||||
|
try {
|
||||||
|
android.widget.FrameLayout.prototype.onDetachedFromWindow.call(this);
|
||||||
|
} catch(eSuperDetach) {}
|
||||||
|
}
|
||||||
|
}, context);
|
||||||
root.setBackgroundColor(self.withAlpha(isDark ? 0xFF000000 : 0xFFFFFFFF, isDark ? 0.58 : 0.42));
|
root.setBackgroundColor(self.withAlpha(isDark ? 0xFF000000 : 0xFFFFFFFF, isDark ? 0.58 : 0.42));
|
||||||
root.setClickable(true);
|
root.setClickable(true);
|
||||||
try { root.setFocusable(true); root.setFocusableInTouchMode(true); } catch(eRootFocus) {}
|
try { root.setFocusable(true); root.setFocusableInTouchMode(true); } catch(eRootFocus) {}
|
||||||
|
try {
|
||||||
|
root.setOnKeyListener(new android.view.View.OnKeyListener({
|
||||||
|
onKey: function(v, keyCode, event) {
|
||||||
|
try {
|
||||||
|
if (keyCode === android.view.KeyEvent.KEYCODE_BACK && event && event.getAction && event.getAction() === android.view.KeyEvent.ACTION_UP) {
|
||||||
|
closePopup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch(eKey) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} catch(eRootKey) {}
|
||||||
|
|
||||||
var card = new android.widget.LinearLayout(context);
|
var popupBackDownX = 0;
|
||||||
|
var popupBackDownY = 0;
|
||||||
|
var popupBackEdge = -1;
|
||||||
|
var popupBackEligible = false;
|
||||||
|
var popupBackActive = false;
|
||||||
|
var popupBackMoved = false;
|
||||||
|
var popupBackVisualActive = false;
|
||||||
|
function beginPopupBackVisual(v) {
|
||||||
|
try {
|
||||||
|
if (popupBackVisualActive || !v) return;
|
||||||
|
popupBackVisualActive = true;
|
||||||
|
// ColorOS overlay 上拖动带 elevation 的圆角卡片容易留下阴影/拖影;拖动期间临时去掉阴影。
|
||||||
|
try { v.animate().cancel(); } catch(eAnimCancel) {}
|
||||||
|
try { v.setAlpha(1); v.setScaleX(1); v.setScaleY(1); } catch(eResetVisual) {}
|
||||||
|
try { v.setElevation(0); } catch(eElev0) {}
|
||||||
|
try { v.setLayerType(android.view.View.LAYER_TYPE_NONE, null); } catch(eLayer0) {}
|
||||||
|
try { v.invalidate(); root.invalidate(); } catch(eInv0) {}
|
||||||
|
} catch(eBeginVisual) {}
|
||||||
|
}
|
||||||
|
function endPopupBackVisual(v) {
|
||||||
|
try {
|
||||||
|
popupBackVisualActive = false;
|
||||||
|
if (!v) return;
|
||||||
|
try { v.setAlpha(1); v.setScaleX(1); v.setScaleY(1); } catch(eResetVisual2) {}
|
||||||
|
try { v.setElevation(self.dp(10)); } catch(eElevRestore) {}
|
||||||
|
try { v.setLayerType(android.view.View.LAYER_TYPE_NONE, null); } catch(eLayerRestore) {}
|
||||||
|
try { v.invalidate(); root.invalidate(); } catch(eInvRestore) {}
|
||||||
|
} catch(eEndVisual) {}
|
||||||
|
}
|
||||||
|
var card = new JavaAdapter(android.widget.LinearLayout, {
|
||||||
|
onInterceptTouchEvent: function(ev) {
|
||||||
|
try {
|
||||||
|
if (!ev) return false;
|
||||||
|
var action = ev.getActionMasked();
|
||||||
|
if (action === android.view.MotionEvent.ACTION_DOWN) {
|
||||||
|
popupBackDownX = ev.getX();
|
||||||
|
popupBackDownY = ev.getY();
|
||||||
|
popupBackEdge = -1;
|
||||||
|
popupBackEligible = false;
|
||||||
|
popupBackActive = false;
|
||||||
|
popupBackMoved = false;
|
||||||
|
var edgeW = self.dp(56);
|
||||||
|
var cw = 0;
|
||||||
|
try { cw = this.getWidth(); } catch(eW) { cw = 0; }
|
||||||
|
if (popupBackDownX <= edgeW) { popupBackEdge = 0; popupBackEligible = true; }
|
||||||
|
else if (cw > 0 && popupBackDownX >= cw - edgeW) { popupBackEdge = 1; popupBackEligible = true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (action === android.view.MotionEvent.ACTION_MOVE) {
|
||||||
|
if (!popupBackEligible) return false;
|
||||||
|
var dx = ev.getX() - popupBackDownX;
|
||||||
|
var dy = ev.getY() - popupBackDownY;
|
||||||
|
var adx = Math.abs(dx);
|
||||||
|
var ady = Math.abs(dy);
|
||||||
|
var validDir = (popupBackEdge === 0 && dx > 0) || (popupBackEdge === 1 && dx < 0);
|
||||||
|
var slop = Math.max(self.dp(8), self.dp(Number(self.config.CLICK_SLOP_DP || 6)));
|
||||||
|
if (validDir && adx > slop && adx > ady * 0.9) {
|
||||||
|
popupBackActive = true;
|
||||||
|
popupBackMoved = true;
|
||||||
|
beginPopupBackVisual(this);
|
||||||
|
// 只识别滑动关闭手势,不再跟手平移卡片;ColorOS overlay 平移会留下上一帧拖影。
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); } catch(eTx) {}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(eIntercept) { try { safeLog(self.L, 'w', 'popup back intercept fail: ' + String(eIntercept)); } catch(eLog) {} }
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onTouchEvent: function(ev) {
|
||||||
|
try {
|
||||||
|
if (!ev || !popupBackActive) return false;
|
||||||
|
var action = ev.getActionMasked();
|
||||||
|
if (action === android.view.MotionEvent.ACTION_MOVE) {
|
||||||
|
var mx = ev.getX() - popupBackDownX;
|
||||||
|
var my = ev.getY() - popupBackDownY;
|
||||||
|
var validDir2 = (popupBackEdge === 0 && mx > 0) || (popupBackEdge === 1 && mx < 0);
|
||||||
|
if (validDir2 && Math.abs(mx) > Math.abs(my) * 0.9) {
|
||||||
|
popupBackMoved = true;
|
||||||
|
// 手势过程中保持卡片固定,避免 overlay translation 产生拖影/重复影像。
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); } catch(eMoveReset) {}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (action === android.view.MotionEvent.ACTION_UP || action === android.view.MotionEvent.ACTION_CANCEL) {
|
||||||
|
var ux = ev.getX() - popupBackDownX;
|
||||||
|
var uy = ev.getY() - popupBackDownY;
|
||||||
|
var okDir = (popupBackEdge === 0 && ux > self.dp(72)) || (popupBackEdge === 1 && ux < -self.dp(72));
|
||||||
|
var ok = action === android.view.MotionEvent.ACTION_UP && popupBackMoved && okDir && Math.abs(ux) > Math.abs(uy) * 0.9;
|
||||||
|
var dir = popupBackEdge === 1 ? -1 : 1;
|
||||||
|
popupBackActive = false;
|
||||||
|
popupBackEligible = false;
|
||||||
|
popupBackMoved = false;
|
||||||
|
popupBackEdge = -1;
|
||||||
|
if (ok) {
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); } catch(eOkReset) {}
|
||||||
|
endPopupBackVisual(this);
|
||||||
|
closePopup();
|
||||||
|
} else {
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); } catch(eCancelReset) {}
|
||||||
|
endPopupBackVisual(this);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch(eTouch) {
|
||||||
|
popupBackActive = false;
|
||||||
|
popupBackEligible = false;
|
||||||
|
popupBackMoved = false;
|
||||||
|
popupBackEdge = -1;
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); endPopupBackVisual(this); } catch(eReset) {}
|
||||||
|
try { safeLog(self.L, 'w', 'popup back touch fail: ' + String(eTouch)); } catch(eLog2) {}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, context);
|
||||||
card.setOrientation(android.widget.LinearLayout.VERTICAL);
|
card.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||||
var cardLp = new android.widget.FrameLayout.LayoutParams(panelWidth, panelHeight);
|
var cardLp = new android.widget.FrameLayout.LayoutParams(panelWidth, panelHeight);
|
||||||
cardLp.gravity = android.view.Gravity.CENTER;
|
cardLp.gravity = android.view.Gravity.CENTER;
|
||||||
@@ -4674,6 +4831,15 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
));
|
));
|
||||||
card.addView(scroll);
|
card.addView(scroll);
|
||||||
|
|
||||||
|
var footer = new android.widget.LinearLayout(context);
|
||||||
|
footer.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||||
|
footer.setVisibility(android.view.View.GONE);
|
||||||
|
try { footer.setPadding(0, self.dp(6), 0, 0); } catch(eFooterPad) {}
|
||||||
|
card.addView(footer, new android.widget.LinearLayout.LayoutParams(
|
||||||
|
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
));
|
||||||
|
|
||||||
root.addView(card);
|
root.addView(card);
|
||||||
|
|
||||||
root.setOnClickListener(new android.view.View.OnClickListener({
|
root.setOnClickListener(new android.view.View.OnClickListener({
|
||||||
@@ -4698,8 +4864,35 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
| android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
| android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
||||||
|
|
||||||
try { wm.addView(root, lp); } catch(eAdd) { safeLog(self.L, 'e', "popup addView fail: " + String(eAdd)); return null; }
|
try { wm.addView(root, lp); } catch(eAdd) { safeLog(self.L, 'e', "popup addView fail: " + String(eAdd)); return null; }
|
||||||
|
try {
|
||||||
|
root.requestFocus();
|
||||||
|
root.post(new java.lang.Runnable({ run: function() {
|
||||||
|
try {
|
||||||
|
if (popupClosed) return;
|
||||||
|
var dispatcher = null;
|
||||||
|
try { dispatcher = root.findOnBackInvokedDispatcher(); } catch(eFindBack) { dispatcher = null; }
|
||||||
|
if (!dispatcher) return;
|
||||||
|
var cbCls = java.lang.Class.forName("android.window.OnBackInvokedCallback");
|
||||||
|
var cb = new JavaAdapter(cbCls, { onBackInvoked: function() { closePopup(); } });
|
||||||
|
var priority = 0;
|
||||||
|
try { priority = android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT; } catch(ePri) { priority = 0; }
|
||||||
|
dispatcher.registerOnBackInvokedCallback(priority, cb);
|
||||||
|
popupBackDispatcher = dispatcher;
|
||||||
|
popupBackCallback = cb;
|
||||||
|
} catch(eRegPopupBack) {
|
||||||
|
try { safeLog(self.L, 'w', 'popup back callback register fail: ' + String(eRegPopupBack)); } catch(eLogReg) {}
|
||||||
|
}
|
||||||
|
}}));
|
||||||
|
} catch(eReqFocus) {}
|
||||||
|
|
||||||
function closePopup() {
|
function closePopup() {
|
||||||
|
if (popupClosed) return;
|
||||||
|
popupClosed = true;
|
||||||
|
try {
|
||||||
|
if (popupBackDispatcher && popupBackCallback) popupBackDispatcher.unregisterOnBackInvokedCallback(popupBackCallback);
|
||||||
|
} catch(eUnregPopupBack) {}
|
||||||
|
popupBackDispatcher = null;
|
||||||
|
popupBackCallback = null;
|
||||||
try { wm.removeView(root); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
try { wm.removeView(root); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||||
if (typeof onDismiss === "function") {
|
if (typeof onDismiss === "function") {
|
||||||
try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); }
|
try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); }
|
||||||
@@ -4709,8 +4902,14 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
if (typeof builder === "function") {
|
if (typeof builder === "function") {
|
||||||
try { builder(content, closePopup); } catch(eB) { safeLog(self.L, 'e', "popup builder fail: " + String(eB)); }
|
try { builder(content, closePopup); } catch(eB) { safeLog(self.L, 'e', "popup builder fail: " + String(eB)); }
|
||||||
}
|
}
|
||||||
|
if (typeof footerBuilder === "function") {
|
||||||
|
try {
|
||||||
|
footerBuilder(footer, closePopup);
|
||||||
|
if (footer.getChildCount && footer.getChildCount() > 0) footer.setVisibility(android.view.View.VISIBLE);
|
||||||
|
} catch(eF) { safeLog(self.L, 'e', "popup footer builder fail: " + String(eF)); }
|
||||||
|
}
|
||||||
|
|
||||||
return { close: closePopup, content: content };
|
return { close: closePopup, content: content, footer: footer };
|
||||||
};
|
};
|
||||||
|
|
||||||
// 兼容旧入口:旧 ToolHub.js 不会自动加载新增 th_14_color_picker.js,
|
// 兼容旧入口:旧 ToolHub.js 不会自动加载新增 th_14_color_picker.js,
|
||||||
|
|||||||
@@ -559,6 +559,7 @@ FloatBallAppWM.prototype.closeToolApp = function() {
|
|||||||
this.state.toolAppBackPreviewEntryKey = null;
|
this.state.toolAppBackPreviewEntryKey = null;
|
||||||
this.state.toolAppTitleView = null;
|
this.state.toolAppTitleView = null;
|
||||||
this.state.toolAppBackButton = null;
|
this.state.toolAppBackButton = null;
|
||||||
|
this.state.toolAppScrollY = 0;
|
||||||
} catch (e) { safeLog(this.L, 'e', "closeToolApp fail: " + String(e)); }
|
} catch (e) { safeLog(this.L, 'e', "closeToolApp fail: " + String(e)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -662,7 +663,7 @@ FloatBallAppWM.prototype.bumpToolAppStackVersion = function() {
|
|||||||
v = v + 1;
|
v = v + 1;
|
||||||
if (v > 1000000000) v = 1;
|
if (v > 1000000000) v = 1;
|
||||||
this.state.toolAppNavStackVersion = v;
|
this.state.toolAppNavStackVersion = v;
|
||||||
this.clearToolAppBackPreview(false);
|
if (!this.state.keepToolAppBackPreviewDuringPop) this.clearToolAppBackPreview(false);
|
||||||
return v;
|
return v;
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -673,9 +674,94 @@ FloatBallAppWM.prototype.getToolAppSnapshotKey = function(entry) {
|
|||||||
return String(entry && entry.route || "");
|
return String(entry && entry.route || "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FloatBallAppWM.prototype.findToolAppFirstScrollView = function(root) {
|
||||||
|
try {
|
||||||
|
if (!root) return null;
|
||||||
|
if (root instanceof android.widget.ScrollView) return root;
|
||||||
|
if (!root.getChildCount) return null;
|
||||||
|
var count = root.getChildCount();
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var found = this.findToolAppFirstScrollView(root.getChildAt(i));
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatBallAppWM.prototype.captureToolAppCurrentScrollY = function() {
|
||||||
|
try {
|
||||||
|
var host = this.state ? this.state.toolAppContentHost : null;
|
||||||
|
var sv = this.findToolAppFirstScrollView ? this.findToolAppFirstScrollView(host) : null;
|
||||||
|
if (!sv) return null;
|
||||||
|
var y = Number(sv.getScrollY ? sv.getScrollY() : 0);
|
||||||
|
if (isNaN(y) || y < 0) y = 0;
|
||||||
|
return Math.floor(y);
|
||||||
|
} catch(e) {}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatBallAppWM.prototype.saveToolAppCurrentStackScroll = function() {
|
||||||
|
try {
|
||||||
|
var st = this.state.toolAppNavStack;
|
||||||
|
if (!st || !st.length) return false;
|
||||||
|
var y = this.captureToolAppCurrentScrollY ? this.captureToolAppCurrentScrollY() : null;
|
||||||
|
if (y === null || y === undefined) return false;
|
||||||
|
st[st.length - 1].toolAppScrollY = y;
|
||||||
|
this.state.toolAppScrollY = y;
|
||||||
|
return true;
|
||||||
|
} catch(e) {}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatBallAppWM.prototype.restoreToolAppScrollLater = function(root, entry, hideUntilRestored) {
|
||||||
|
try {
|
||||||
|
if (!root) return false;
|
||||||
|
var y = 0;
|
||||||
|
if (entry && entry.toolAppScrollY !== undefined && entry.toolAppScrollY !== null) y = Number(entry.toolAppScrollY);
|
||||||
|
else if (this.state && this.state.toolAppScrollY !== undefined && this.state.toolAppScrollY !== null) y = Number(this.state.toolAppScrollY);
|
||||||
|
if (isNaN(y) || y < 0) y = 0;
|
||||||
|
y = Math.floor(y);
|
||||||
|
if (y <= 0) return false;
|
||||||
|
var self = this;
|
||||||
|
var shouldHide = !!hideUntilRestored;
|
||||||
|
if (shouldHide) {
|
||||||
|
try { root.setAlpha(0.01); } catch(eHide) {}
|
||||||
|
}
|
||||||
|
root.post(new java.lang.Runnable({ run: function() {
|
||||||
|
try {
|
||||||
|
var sv = self.findToolAppFirstScrollView ? self.findToolAppFirstScrollView(root) : null;
|
||||||
|
if (sv) sv.scrollTo(0, y);
|
||||||
|
} catch(ePost) {}
|
||||||
|
try {
|
||||||
|
root.post(new java.lang.Runnable({ run: function() {
|
||||||
|
try {
|
||||||
|
var sv2 = self.findToolAppFirstScrollView ? self.findToolAppFirstScrollView(root) : null;
|
||||||
|
if (sv2) sv2.scrollTo(0, y);
|
||||||
|
} catch(ePost2) {}
|
||||||
|
if (shouldHide) {
|
||||||
|
try { root.setAlpha(1.0); } catch(eShow) {}
|
||||||
|
}
|
||||||
|
}}));
|
||||||
|
} catch(ePostAgain) {
|
||||||
|
if (shouldHide) {
|
||||||
|
try { root.setAlpha(1.0); } catch(eShow2) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}));
|
||||||
|
return true;
|
||||||
|
} catch(e) {
|
||||||
|
try { if (root) root.setAlpha(1.0); } catch(eRestoreAlpha) {}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
FloatBallAppWM.prototype.captureToolAppPageSnapshot = function(route) {
|
FloatBallAppWM.prototype.captureToolAppPageSnapshot = function(route) {
|
||||||
var r = this.isToolAppRoute(route) ? String(route) : (this.isToolAppRoute(this.state.toolAppRoute) ? String(this.state.toolAppRoute) : "settings");
|
var r = this.isToolAppRoute(route) ? String(route) : (this.isToolAppRoute(this.state.toolAppRoute) ? String(this.state.toolAppRoute) : "settings");
|
||||||
var s = this.state || {};
|
var s = this.state || {};
|
||||||
|
var liveScrollY = null;
|
||||||
|
try {
|
||||||
|
if (String(s.toolAppRoute || "") === r && this.captureToolAppCurrentScrollY) liveScrollY = this.captureToolAppCurrentScrollY();
|
||||||
|
} catch(eLiveScroll) { liveScrollY = null; }
|
||||||
var entry = {
|
var entry = {
|
||||||
route: r,
|
route: r,
|
||||||
settingsGroupKey: (s.settingsGroupKey !== undefined && s.settingsGroupKey !== null) ? String(s.settingsGroupKey) : "",
|
settingsGroupKey: (s.settingsGroupKey !== undefined && s.settingsGroupKey !== null) ? String(s.settingsGroupKey) : "",
|
||||||
@@ -689,7 +775,8 @@ FloatBallAppWM.prototype.captureToolAppPageSnapshot = function(route) {
|
|||||||
toolAppSubPage: (s.toolAppSubPage !== undefined) ? s.toolAppSubPage : null,
|
toolAppSubPage: (s.toolAppSubPage !== undefined) ? s.toolAppSubPage : null,
|
||||||
toolAppSubKey: (s.toolAppSubKey !== undefined) ? s.toolAppSubKey : null,
|
toolAppSubKey: (s.toolAppSubKey !== undefined) ? s.toolAppSubKey : null,
|
||||||
toolAppSubPayload: (s.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(s.toolAppSubPayload, 0) : null,
|
toolAppSubPayload: (s.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(s.toolAppSubPayload, 0) : null,
|
||||||
toolAppPayload: (s.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(s.toolAppPayload, 0) : null
|
toolAppPayload: (s.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(s.toolAppPayload, 0) : null,
|
||||||
|
toolAppScrollY: (String(s.toolAppRoute || "") === r) ? ((liveScrollY !== null && liveScrollY !== undefined) ? liveScrollY : ((s.toolAppScrollY !== undefined) ? s.toolAppScrollY : 0)) : 0
|
||||||
};
|
};
|
||||||
if (r !== "settings_group") entry.settingsGroupKey = "";
|
if (r !== "settings_group") entry.settingsGroupKey = "";
|
||||||
if (r !== "settings") { entry.settingsHomeSelectedItemId = null; entry.settingsHomeSelectedCategoryId = null; }
|
if (r !== "settings") { entry.settingsHomeSelectedItemId = null; entry.settingsHomeSelectedCategoryId = null; }
|
||||||
@@ -719,6 +806,8 @@ FloatBallAppWM.prototype.applyToolAppPageSnapshot = function(entry) {
|
|||||||
this.state.toolAppSubKey = (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null;
|
this.state.toolAppSubKey = (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null;
|
||||||
this.state.toolAppSubPayload = (entry.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppSubPayload, 0) : null;
|
this.state.toolAppSubPayload = (entry.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppSubPayload, 0) : null;
|
||||||
this.state.toolAppPayload = (entry.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppPayload, 0) : null;
|
this.state.toolAppPayload = (entry.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppPayload, 0) : null;
|
||||||
|
this.state.toolAppScrollY = (entry.toolAppScrollY !== undefined && entry.toolAppScrollY !== null) ? Number(entry.toolAppScrollY) : 0;
|
||||||
|
if (isNaN(this.state.toolAppScrollY) || this.state.toolAppScrollY < 0) this.state.toolAppScrollY = 0;
|
||||||
return true;
|
return true;
|
||||||
} catch(e) { safeLog(this.L, 'w', "apply tool app snapshot fail: " + String(e)); }
|
} catch(e) { safeLog(this.L, 'w', "apply tool app snapshot fail: " + String(e)); }
|
||||||
return false;
|
return false;
|
||||||
@@ -739,7 +828,8 @@ FloatBallAppWM.prototype.cloneToolAppPageSnapshot = function(entry) {
|
|||||||
toolAppSubPage: (entry.toolAppSubPage !== undefined) ? entry.toolAppSubPage : null,
|
toolAppSubPage: (entry.toolAppSubPage !== undefined) ? entry.toolAppSubPage : null,
|
||||||
toolAppSubKey: (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null,
|
toolAppSubKey: (entry.toolAppSubKey !== undefined) ? entry.toolAppSubKey : null,
|
||||||
toolAppSubPayload: (entry.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppSubPayload, 0) : null,
|
toolAppSubPayload: (entry.toolAppSubPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppSubPayload, 0) : null,
|
||||||
toolAppPayload: (entry.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppPayload, 0) : null
|
toolAppPayload: (entry.toolAppPayload !== undefined) ? this.cloneToolAppSnapshotValue(entry.toolAppPayload, 0) : null,
|
||||||
|
toolAppScrollY: (entry.toolAppScrollY !== undefined && entry.toolAppScrollY !== null) ? Number(entry.toolAppScrollY) : 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -762,6 +852,9 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
|
|||||||
} catch(eSpec) {
|
} catch(eSpec) {
|
||||||
spec = null;
|
spec = null;
|
||||||
}
|
}
|
||||||
|
var shellPad = spec ? spec.shellPadding : this.dp(6);
|
||||||
|
var shellTopPad = shellPad;
|
||||||
|
var outerRadius = spec ? spec.outerRadius : this.dp(26);
|
||||||
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
|
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
|
||||||
|
|
||||||
var isDark = this.isDarkTheme();
|
var isDark = this.isDarkTheme();
|
||||||
@@ -772,8 +865,8 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
|
|||||||
|
|
||||||
var body = new android.widget.LinearLayout(context);
|
var body = new android.widget.LinearLayout(context);
|
||||||
body.setOrientation(android.widget.LinearLayout.VERTICAL);
|
body.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||||
body.setPadding(this.dp(6), this.dp(6), this.dp(6), this.dp(8));
|
body.setPadding(shellPad, shellTopPad, shellPad, shellPad);
|
||||||
body.setBackground(this.ui.createStrokeDrawable(T.bg, this.withAlpha(T.stroke, isDark ? 0.42 : 0.70), this.dp(1), this.dp(26)));
|
body.setBackground(this.ui.createStrokeDrawable(T.bg, this.withAlpha(T.stroke, isDark ? 0.30 : 0.46), this.dp(1), outerRadius));
|
||||||
try { body.setClipToOutline(true); } catch(eClip) {}
|
try { body.setClipToOutline(true); } catch(eClip) {}
|
||||||
try { body.setElevation(this.dp((spec && (spec.isExpandedWidth || spec.isWideWidth)) ? 7 : 10)); } catch (eElev) {}
|
try { body.setElevation(this.dp((spec && (spec.isExpandedWidth || spec.isWideWidth)) ? 7 : 10)); } catch (eElev) {}
|
||||||
|
|
||||||
@@ -827,7 +920,7 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
|
|||||||
try { btnClose.setBackground(this.ui.createStrokeDrawable(T.primarySoft, this.withAlpha(T.primaryDeep, isDark ? 0.30 : 0.22), this.dp(1), this.dp(18))); } catch(eRightBg) {}
|
try { btnClose.setBackground(this.ui.createStrokeDrawable(T.primarySoft, this.withAlpha(T.primaryDeep, isDark ? 0.30 : 0.22), this.dp(1), this.dp(18))); } catch(eRightBg) {}
|
||||||
bar.addView(btnClose, new android.widget.LinearLayout.LayoutParams(this.dp(104), this.dp(38)));
|
bar.addView(btnClose, new android.widget.LinearLayout.LayoutParams(this.dp(104), this.dp(38)));
|
||||||
var barLp = new android.widget.LinearLayout.LayoutParams(-1, topBarHeight);
|
var barLp = new android.widget.LinearLayout.LayoutParams(-1, topBarHeight);
|
||||||
barLp.setMargins(this.dp(8), this.dp(8), this.dp(8), this.dp(4));
|
barLp.setMargins(this.dp(8), this.dp(2), this.dp(8), this.dp(4));
|
||||||
body.addView(bar, barLp);
|
body.addView(bar, barLp);
|
||||||
|
|
||||||
var host = new android.widget.FrameLayout(context);
|
var host = new android.widget.FrameLayout(context);
|
||||||
@@ -835,6 +928,7 @@ FloatBallAppWM.prototype.buildToolAppPreviewBody = function(entry) {
|
|||||||
try { raw.setBackground(null); } catch (eBg) {}
|
try { raw.setBackground(null); } catch (eBg) {}
|
||||||
try { raw.setElevation(0); } catch (eEl) {}
|
try { raw.setElevation(0); } catch (eEl) {}
|
||||||
host.addView(raw, new android.widget.FrameLayout.LayoutParams(-1, -1));
|
host.addView(raw, new android.widget.FrameLayout.LayoutParams(-1, -1));
|
||||||
|
try { if (this.restoreToolAppScrollLater) this.restoreToolAppScrollLater(raw, entry); } catch(ePreviewScroll) {}
|
||||||
var hostLp = new android.widget.LinearLayout.LayoutParams(-1, 0, 1);
|
var hostLp = new android.widget.LinearLayout.LayoutParams(-1, 0, 1);
|
||||||
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));
|
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);
|
body.addView(host, hostLp);
|
||||||
@@ -1020,10 +1114,9 @@ FloatBallAppWM.prototype.applyToolAppBackPreviewProgress = function(edge, progre
|
|||||||
if (body) {
|
if (body) {
|
||||||
try { body.animate().cancel(); } catch(eCancelBody) {}
|
try { body.animate().cancel(); } catch(eCancelBody) {}
|
||||||
body.setTranslationX(bodyMove);
|
body.setTranslationX(bodyMove);
|
||||||
body.setAlpha(1.0 - 0.10 * eased);
|
body.setAlpha(1.0);
|
||||||
var s = 1.0 - 0.015 * eased;
|
body.setScaleX(1.0);
|
||||||
body.setScaleX(s);
|
body.setScaleY(1.0);
|
||||||
body.setScaleY(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1045,11 +1138,10 @@ FloatBallAppWM.prototype.applyToolAppBackPreviewProgress = function(edge, progre
|
|||||||
}
|
}
|
||||||
} catch(eMoveLog) {}
|
} catch(eMoveLog) {}
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev.setAlpha(0.88 + 0.12 * eased);
|
prev.setAlpha(1.0);
|
||||||
prev.setTranslationX(-dir * this.dp(24) * (1.0 - eased));
|
prev.setTranslationX(0);
|
||||||
var ps = 0.975 + 0.025 * eased;
|
prev.setScaleX(1.0);
|
||||||
prev.setScaleX(ps);
|
prev.setScaleY(1.0);
|
||||||
prev.setScaleY(ps);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (e) { safeLog(this.L, 'w', "apply tool app back preview fail: " + String(e)); }
|
} catch (e) { safeLog(this.L, 'w', "apply tool app back preview fail: " + String(e)); }
|
||||||
@@ -1071,10 +1163,19 @@ FloatBallAppWM.prototype.finishToolAppBackPreview = function(edge, complete) {
|
|||||||
try { w = Number((this.state.toolAppRoot && this.state.toolAppRoot.getWidth && this.state.toolAppRoot.getWidth()) || 0); } catch (eW1) {}
|
try { w = Number((this.state.toolAppRoot && this.state.toolAppRoot.getWidth && this.state.toolAppRoot.getWidth()) || 0); } catch (eW1) {}
|
||||||
}
|
}
|
||||||
if (!w || w < this.dp(120)) w = this.dp(320);
|
if (!w || w < this.dp(120)) w = this.dp(320);
|
||||||
try { if (prev) prev.animate().translationX(0).alpha(1).scaleX(1).scaleY(1).setDuration(180).setInterpolator(decel).start(); } catch(ePrev) {}
|
try { if (prev) prev.animate().translationX(0).alpha(1).scaleX(1).scaleY(1).setDuration(120).setInterpolator(decel).start(); } catch(ePrev) {}
|
||||||
body.animate().translationX(dir * w).alpha(0.90).scaleX(0.985).scaleY(0.985).setDuration(180).setInterpolator(decel).withEndAction(new java.lang.Runnable({
|
body.animate().translationX(dir * w).alpha(1).scaleX(1).scaleY(1).setDuration(160).setInterpolator(decel).withEndAction(new java.lang.Runnable({
|
||||||
run: function() {
|
run: function() {
|
||||||
try { self.resetToolAppBackWindowFollow(); } catch(eResetFollow) {}
|
try { self.resetToolAppBackWindowFollow(); } catch(eResetFollow) {}
|
||||||
|
try { self.state.keepToolAppBackPreviewDuringPop = true; } catch(eKeepPreview) {}
|
||||||
|
try { self.popToolAppPage("edge_swipe_back"); } catch (ePop) {}
|
||||||
|
try { self.state.keepToolAppBackPreviewDuringPop = false; } catch(eKeepPreview2) {}
|
||||||
|
try {
|
||||||
|
var rootAfter = self.state.toolAppRoot;
|
||||||
|
if (rootAfter) {
|
||||||
|
rootAfter.post(new java.lang.Runnable({ run: function() {
|
||||||
|
try {
|
||||||
|
rootAfter.post(new java.lang.Runnable({ run: function() {
|
||||||
try {
|
try {
|
||||||
if (self.state.toolAppRoot) self.state.toolAppRoot.setTranslationX(0);
|
if (self.state.toolAppRoot) self.state.toolAppRoot.setTranslationX(0);
|
||||||
if (self.state.toolAppBody) {
|
if (self.state.toolAppBody) {
|
||||||
@@ -1083,16 +1184,26 @@ FloatBallAppWM.prototype.finishToolAppBackPreview = function(edge, complete) {
|
|||||||
self.state.toolAppBody.setScaleX(1);
|
self.state.toolAppBody.setScaleX(1);
|
||||||
self.state.toolAppBody.setScaleY(1);
|
self.state.toolAppBody.setScaleY(1);
|
||||||
}
|
}
|
||||||
} catch(eResetView) {}
|
} catch(eResetViewLater) {}
|
||||||
try { self.clearToolAppBackPreview(true); } catch (eClear) {}
|
try { self.clearToolAppBackPreview(true); } catch (eClearLater) {}
|
||||||
try { self.popToolAppPage("edge_swipe_back"); } catch (ePop) {}
|
}}));
|
||||||
|
} catch(ePost2) {
|
||||||
|
try { self.clearToolAppBackPreview(true); } catch (eClearPostFail) {}
|
||||||
|
}
|
||||||
|
}}));
|
||||||
|
} else {
|
||||||
|
try { self.clearToolAppBackPreview(true); } catch (eClearNoRoot) {}
|
||||||
|
}
|
||||||
|
} catch(eLater) {
|
||||||
|
try { self.clearToolAppBackPreview(true); } catch (eClearLaterFail) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})).start();
|
})).start();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (body) {
|
if (body) {
|
||||||
var cancelInterp = new android.view.animation.AccelerateDecelerateInterpolator();
|
var cancelInterp = new android.view.animation.AccelerateDecelerateInterpolator();
|
||||||
try { if (prev) prev.animate().translationX(-dir * self.dp(24)).alpha(0.88).scaleX(0.975).scaleY(0.975).setDuration(200).setInterpolator(cancelInterp).start(); } catch(ePrev2) {}
|
try { if (prev) prev.animate().translationX(0).alpha(1).scaleX(1).scaleY(1).setDuration(160).setInterpolator(cancelInterp).start(); } catch(ePrev2) {}
|
||||||
body.animate().translationX(0).alpha(1).scaleX(1).scaleY(1).setDuration(200).setInterpolator(cancelInterp).withEndAction(new java.lang.Runnable({
|
body.animate().translationX(0).alpha(1).scaleX(1).scaleY(1).setDuration(200).setInterpolator(cancelInterp).withEndAction(new java.lang.Runnable({
|
||||||
run: function() {
|
run: function() {
|
||||||
try { self.resetToolAppBackWindowFollow(); } catch(eResetFollow2) {}
|
try { self.resetToolAppBackWindowFollow(); } catch(eResetFollow2) {}
|
||||||
@@ -1261,6 +1372,9 @@ FloatBallAppWM.prototype.buildToolAppShell = function(contentView, title, canBac
|
|||||||
try { if (this.applySettingsTheme) this.applySettingsTheme(T, isDark, C, cfgTpl); } catch(eTheme) { safeLog(null, 'e', "catch " + String(eTheme)); }
|
try { if (this.applySettingsTheme) this.applySettingsTheme(T, isDark, C, cfgTpl); } catch(eTheme) { safeLog(null, 'e', "catch " + String(eTheme)); }
|
||||||
var spec = this.getToolAppResponsiveSpec ? this.getToolAppResponsiveSpec() : null;
|
var spec = this.getToolAppResponsiveSpec ? this.getToolAppResponsiveSpec() : null;
|
||||||
var shellPad = spec ? spec.shellPadding : this.dp(6);
|
var shellPad = spec ? spec.shellPadding : this.dp(6);
|
||||||
|
var shellTopPad = shellPad;
|
||||||
|
// ToolApp 是 WindowManager 浮层卡片,不需要额外叠加状态栏 inset;
|
||||||
|
// 否则一级/二级页面标题上方会出现一块空白。
|
||||||
var outerRadius = spec ? spec.outerRadius : this.dp(26);
|
var outerRadius = spec ? spec.outerRadius : this.dp(26);
|
||||||
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
|
var topBarHeight = spec ? spec.topBarHeight : this.dp(56);
|
||||||
var rootDownX = 0;
|
var rootDownX = 0;
|
||||||
@@ -1420,7 +1534,7 @@ FloatBallAppWM.prototype.buildToolAppShell = function(contentView, title, canBac
|
|||||||
var body = new android.widget.LinearLayout(context);
|
var body = new android.widget.LinearLayout(context);
|
||||||
body.setOrientation(android.widget.LinearLayout.VERTICAL);
|
body.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||||
// 外层薄荷容器本身就是整张“岛屿设置”卡片:四角统一圆角,并给底部留出完整收口。
|
// 外层薄荷容器本身就是整张“岛屿设置”卡片:四角统一圆角,并给底部留出完整收口。
|
||||||
body.setPadding(shellPad, shellPad, shellPad, shellPad);
|
body.setPadding(shellPad, shellTopPad, shellPad, shellPad);
|
||||||
body.setBackground(this.ui.createStrokeDrawable(T.bg, this.withAlpha(T.stroke, isDark ? 0.30 : 0.46), this.dp(1), outerRadius));
|
body.setBackground(this.ui.createStrokeDrawable(T.bg, this.withAlpha(T.stroke, isDark ? 0.30 : 0.46), this.dp(1), outerRadius));
|
||||||
try { body.setClipToOutline(true); } catch(eClip) {}
|
try { body.setClipToOutline(true); } catch(eClip) {}
|
||||||
try { body.setElevation(this.dp((spec && (spec.isExpandedWidth || spec.isWideWidth)) ? 7 : 10)); } catch(eElev) { safeLog(null, 'e', "catch " + String(eElev)); }
|
try { body.setElevation(this.dp((spec && (spec.isExpandedWidth || spec.isWideWidth)) ? 7 : 10)); } catch(eElev) { safeLog(null, 'e', "catch " + String(eElev)); }
|
||||||
@@ -1469,7 +1583,7 @@ FloatBallAppWM.prototype.buildToolAppShell = function(contentView, title, canBac
|
|||||||
try { btnClose.setBackground(this.ui.createStrokeDrawable(T.primarySoft, this.withAlpha(T.primaryDeep, isDark ? 0.30 : 0.22), this.dp(1), this.dp(18))); } catch(eRightBg) {}
|
try { btnClose.setBackground(this.ui.createStrokeDrawable(T.primarySoft, this.withAlpha(T.primaryDeep, isDark ? 0.30 : 0.22), this.dp(1), this.dp(18))); } catch(eRightBg) {}
|
||||||
bar.addView(btnClose, new android.widget.LinearLayout.LayoutParams(this.dp(104), this.dp(38)));
|
bar.addView(btnClose, new android.widget.LinearLayout.LayoutParams(this.dp(104), this.dp(38)));
|
||||||
var barLp = new android.widget.LinearLayout.LayoutParams(-1, topBarHeight);
|
var barLp = new android.widget.LinearLayout.LayoutParams(-1, topBarHeight);
|
||||||
barLp.setMargins(this.dp(8), this.dp(8), this.dp(8), this.dp(4));
|
barLp.setMargins(this.dp(8), this.dp(2), this.dp(8), this.dp(4));
|
||||||
body.addView(bar, barLp);
|
body.addView(bar, barLp);
|
||||||
|
|
||||||
var host = new android.widget.FrameLayout(context);
|
var host = new android.widget.FrameLayout(context);
|
||||||
@@ -1531,6 +1645,11 @@ FloatBallAppWM.prototype.setToolAppContent = function(contentView) {
|
|||||||
try { contentView.setBackground(null); } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
try { contentView.setBackground(null); } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
||||||
try { contentView.setElevation(0); } catch(eEl) { safeLog(null, 'e', "catch " + String(eEl)); }
|
try { contentView.setElevation(0); } catch(eEl) { safeLog(null, 'e', "catch " + String(eEl)); }
|
||||||
host.addView(contentView, new android.widget.FrameLayout.LayoutParams(-1, -1));
|
host.addView(contentView, new android.widget.FrameLayout.LayoutParams(-1, -1));
|
||||||
|
try {
|
||||||
|
var st = this.state.toolAppNavStack || [];
|
||||||
|
var top = st.length ? st[st.length - 1] : null;
|
||||||
|
if (this.restoreToolAppScrollLater) this.restoreToolAppScrollLater(contentView, top, true);
|
||||||
|
} catch(eRestoreScroll) {}
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
safeLog(this.L, 'e', "setToolAppContent fail: " + String(e));
|
safeLog(this.L, 'e', "setToolAppContent fail: " + String(e));
|
||||||
@@ -1538,6 +1657,23 @@ FloatBallAppWM.prototype.setToolAppContent = function(contentView) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FloatBallAppWM.prototype.getToolAppStatusBarInsetPx = function() {
|
||||||
|
var inset = 0;
|
||||||
|
try {
|
||||||
|
var res = context.getResources();
|
||||||
|
var id = res.getIdentifier("status_bar_height", "dimen", "android");
|
||||||
|
if (id > 0) inset = Number(res.getDimensionPixelSize(id) || 0);
|
||||||
|
} catch(eRes) {
|
||||||
|
inset = 0;
|
||||||
|
}
|
||||||
|
if (isNaN(inset) || inset < 0) inset = 0;
|
||||||
|
try {
|
||||||
|
var maxInset = this.dp(48);
|
||||||
|
if (inset > maxInset) inset = maxInset;
|
||||||
|
} catch(eClamp) {}
|
||||||
|
return Math.floor(inset);
|
||||||
|
};
|
||||||
|
|
||||||
FloatBallAppWM.prototype.calculateToolAppLayout = function(shell) {
|
FloatBallAppWM.prototype.calculateToolAppLayout = function(shell) {
|
||||||
var sw = Math.max(1, Number(this.state.screen && this.state.screen.w || 0));
|
var sw = Math.max(1, Number(this.state.screen && this.state.screen.w || 0));
|
||||||
var sh = Math.max(1, Number(this.state.screen && this.state.screen.h || 0));
|
var sh = Math.max(1, Number(this.state.screen && this.state.screen.h || 0));
|
||||||
@@ -1548,27 +1684,30 @@ FloatBallAppWM.prototype.calculateToolAppLayout = function(shell) {
|
|||||||
var isLandscape = spec ? spec.isLandscape : (sw > sh);
|
var isLandscape = spec ? spec.isLandscape : (sw > sh);
|
||||||
var shortSide = Math.min(sw, sh);
|
var shortSide = Math.min(sw, sh);
|
||||||
var longSide = Math.max(sw, sh);
|
var longSide = Math.max(sw, sh);
|
||||||
var marginX = this.dp(12), marginTop = this.dp(14), marginBottom = this.dp(14);
|
var marginX = this.dp(12), marginTop = 0, marginBottom = this.dp(14);
|
||||||
|
var statusInset = 0;
|
||||||
|
try { statusInset = this.getToolAppStatusBarInsetPx ? this.getToolAppStatusBarInsetPx() : 0; } catch(eInset) { statusInset = 0; }
|
||||||
|
if (isNaN(statusInset) || statusInset < 0) statusInset = 0;
|
||||||
var targetW, targetH;
|
var targetW, targetH;
|
||||||
if (spec && (spec.isCompactWidth || shortSide < this.dp(420))) {
|
if (spec && (spec.isCompactWidth || shortSide < this.dp(420))) {
|
||||||
marginX = this.dp(isLandscape ? 8 : 10); marginTop = this.dp(isLandscape ? 6 : 14); marginBottom = this.dp(isLandscape ? 6 : 14);
|
marginX = this.dp(isLandscape ? 8 : 10); marginTop = 0; marginBottom = this.dp(isLandscape ? 6 : 14);
|
||||||
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2);
|
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2);
|
||||||
targetH = isLandscape ? (sh - marginTop - marginBottom) : Math.min(Math.floor(sh * 0.92), sh - marginTop - marginBottom);
|
targetH = isLandscape ? (sh - marginTop - marginBottom) : Math.min(Math.floor(sh * 0.96), sh - marginTop - marginBottom);
|
||||||
} else if (spec && spec.isMediumWidth) {
|
} else if (spec && spec.isMediumWidth) {
|
||||||
marginX = this.dp(18); marginTop = this.dp(isLandscape ? 10 : 18); marginBottom = this.dp(isLandscape ? 10 : 18);
|
marginX = this.dp(18); marginTop = 0; marginBottom = this.dp(isLandscape ? 10 : 18);
|
||||||
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2); targetH = sh - marginTop - marginBottom;
|
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2); targetH = sh - marginTop - marginBottom;
|
||||||
} else if (spec && (spec.isExpandedWidth || shortSide >= this.dp(720))) {
|
} else if (spec && (spec.isExpandedWidth || shortSide >= this.dp(720))) {
|
||||||
marginX = this.dp(22); marginTop = this.dp(isLandscape ? 18 : 24); marginBottom = this.dp(isLandscape ? 18 : 24);
|
marginX = this.dp(22); marginTop = 0; marginBottom = this.dp(isLandscape ? 18 : 24);
|
||||||
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2); targetH = sh - marginTop - marginBottom;
|
targetW = Math.min(spec.contentMaxWidth, sw - marginX * 2); targetH = sh - marginTop - marginBottom;
|
||||||
} else {
|
} else {
|
||||||
marginX = this.dp(30); marginTop = this.dp(24); marginBottom = this.dp(24);
|
marginX = this.dp(30); marginTop = 0; marginBottom = this.dp(24);
|
||||||
targetW = Math.min(spec ? spec.contentMaxWidth : this.dp(1080), sw - marginX * 2);
|
targetW = Math.min(spec ? spec.contentMaxWidth : this.dp(1080), sw - marginX * 2);
|
||||||
targetH = Math.min(this.dp(860), sh - marginTop - marginBottom);
|
targetH = Math.min(this.dp(900), sh - marginTop - marginBottom);
|
||||||
}
|
}
|
||||||
targetW = Math.max(this.dp(300), Math.min(targetW, sw - marginX * 2));
|
targetW = Math.max(this.dp(300), Math.min(targetW, sw - marginX * 2));
|
||||||
targetH = Math.max(this.dp(320), Math.min(targetH, sh - marginTop - marginBottom));
|
targetH = Math.max(this.dp(320), Math.min(targetH, sh - marginTop - marginBottom));
|
||||||
var x = Math.floor((sw - targetW) / 2);
|
var x = Math.floor((sw - targetW) / 2);
|
||||||
var y = Math.floor((sh - targetH) / 2);
|
var y = marginTop;
|
||||||
if (x < marginX) x = marginX;
|
if (x < marginX) x = marginX;
|
||||||
if (y < marginTop) y = marginTop;
|
if (y < marginTop) y = marginTop;
|
||||||
if (x + targetW > sw - marginX) x = Math.max(0, sw - marginX - targetW);
|
if (x + targetW > sw - marginX) x = Math.max(0, sw - marginX - targetW);
|
||||||
@@ -1592,6 +1731,7 @@ FloatBallAppWM.prototype.showToolApp = function(route, resetStack) {
|
|||||||
this.state.pendingUserCfg = null;
|
this.state.pendingUserCfg = null;
|
||||||
this.state.pendingDirty = false;
|
this.state.pendingDirty = false;
|
||||||
this.state.previewMode = false;
|
this.state.previewMode = false;
|
||||||
|
this.state.toolAppScrollY = 0;
|
||||||
}
|
}
|
||||||
if (resetStack || !this.state.toolAppNavStack || !this.state.toolAppNavStack.length) {
|
if (resetStack || !this.state.toolAppNavStack || !this.state.toolAppNavStack.length) {
|
||||||
this.state.toolAppNavStack = [this.makeToolAppStackEntry(r)];
|
this.state.toolAppNavStack = [this.makeToolAppStackEntry(r)];
|
||||||
@@ -1633,6 +1773,7 @@ FloatBallAppWM.prototype.showToolApp = function(route, resetStack) {
|
|||||||
|
|
||||||
FloatBallAppWM.prototype.pushToolAppPage = function(route) {
|
FloatBallAppWM.prototype.pushToolAppPage = function(route) {
|
||||||
if (!this.isToolAppRoute(route)) return;
|
if (!this.isToolAppRoute(route)) return;
|
||||||
|
try { if (this.saveToolAppCurrentStackScroll) this.saveToolAppCurrentStackScroll(); } catch(eSaveScrollPush) {}
|
||||||
if (!this.state.toolAppNavStack) this.state.toolAppNavStack = [];
|
if (!this.state.toolAppNavStack) this.state.toolAppNavStack = [];
|
||||||
if (this.state.toolAppNavStack.length <= 0) {
|
if (this.state.toolAppNavStack.length <= 0) {
|
||||||
this.state.toolAppNavStack.push(this.makeToolAppStackEntry(this.state.toolAppRoute || "settings"));
|
this.state.toolAppNavStack.push(this.makeToolAppStackEntry(this.state.toolAppRoute || "settings"));
|
||||||
|
|||||||
@@ -128,17 +128,6 @@ FloatBallAppWM.prototype.close = function() {
|
|||||||
|
|
||||||
safeLog(this.L, 'i', "close done");
|
safeLog(this.L, 'i', "close done");
|
||||||
|
|
||||||
// # 清理日志定时器
|
|
||||||
try {
|
|
||||||
if (this.L) {
|
|
||||||
try { this.L._flushBuffer(); } catch (eFlushLog0) { safeLog(this.L, 'e', "logger flush fail: " + String(eFlushLog0)); }
|
|
||||||
if (this.L._flushTimer) {
|
|
||||||
this.L._flushTimer.cancel();
|
|
||||||
this.L._flushTimer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (eLog) {}
|
|
||||||
|
|
||||||
// # 清空缓存
|
// # 清空缓存
|
||||||
try {
|
try {
|
||||||
this._iconLru = null;
|
this._iconLru = null;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"alg": "SHA256withRSA",
|
"alg": "SHA256withRSA",
|
||||||
"files": {
|
"files": {
|
||||||
"th_01_base.js": {
|
"th_01_base.js": {
|
||||||
"sha256": "c77eb730b0a54bfe784ff9fee4f88e3276826dc73ae98a2ef964bf5041632d38",
|
"sha256": "e465a92b21f6819079255719bfe41c28a42ff3716f1d29b399897bc299ef92ec",
|
||||||
"size": 57562
|
"size": 54633
|
||||||
},
|
},
|
||||||
"th_02_core.js": {
|
"th_02_core.js": {
|
||||||
"sha256": "7bfd21df21c137595c3e2a8724b3eb3f0cce82ef0dd18b732de08e9be30b2ba3",
|
"sha256": "7bfd21df21c137595c3e2a8724b3eb3f0cce82ef0dd18b732de08e9be30b2ba3",
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
"size": 42568
|
"size": 42568
|
||||||
},
|
},
|
||||||
"th_05_persistence.js": {
|
"th_05_persistence.js": {
|
||||||
"sha256": "fac67158d57ce23c92dbc4103d1732946b6ea0fde9f55a04edede9a1f201a7da",
|
"sha256": "7fd2a62275bd26fcd940202057480fca7a8a800eaeb1fcb9d52003e255d1ef60",
|
||||||
"size": 14921
|
"size": 14763
|
||||||
},
|
},
|
||||||
"th_06_icon_parser.js": {
|
"th_06_icon_parser.js": {
|
||||||
"sha256": "25b95a5df634a7ee359f3ab798e4d3154a71c24016f7b4bf8a658096644b2484",
|
"sha256": "25b95a5df634a7ee359f3ab798e4d3154a71c24016f7b4bf8a658096644b2484",
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
"size": 1094
|
"size": 1094
|
||||||
},
|
},
|
||||||
"th_11_action.js": {
|
"th_11_action.js": {
|
||||||
"sha256": "a0142d26621f3d076bd1b749f2885af2c0806c9f206e362a3b3680a5d2312b31",
|
"sha256": "1ba348415e891093bcf49619d950e9653e1c7323c3d35f74f6f71bec14b7c9e6",
|
||||||
"size": 13545
|
"size": 13838
|
||||||
},
|
},
|
||||||
"th_12_rebuild.js": {
|
"th_12_rebuild.js": {
|
||||||
"sha256": "7b820e813d2dd8866778fefe8bfeb6aca227bb1a32a89d318de830178f19824f",
|
"sha256": "7b820e813d2dd8866778fefe8bfeb6aca227bb1a32a89d318de830178f19824f",
|
||||||
@@ -54,31 +54,31 @@
|
|||||||
"size": 22308
|
"size": 22308
|
||||||
},
|
},
|
||||||
"th_14_color_picker.js": {
|
"th_14_color_picker.js": {
|
||||||
"sha256": "d3ca89146e31e611e17d703ae9834d82794321e651b6ef156ade006227d231e7",
|
"sha256": "2f6378fbb718d4b31cf11d3047cee6b32af93cfbb932442da29dd05225881432",
|
||||||
"size": 23587
|
"size": 23870
|
||||||
},
|
},
|
||||||
"th_14_icon_picker.js": {
|
"th_14_icon_picker.js": {
|
||||||
"sha256": "1df5c4bf82e68de24d7b89c852a4d9878768451effe086e8ddb86620ecc98c35",
|
"sha256": "1df5c4bf82e68de24d7b89c852a4d9878768451effe086e8ddb86620ecc98c35",
|
||||||
"size": 23906
|
"size": 23906
|
||||||
},
|
},
|
||||||
"th_14_panels.js": {
|
"th_14_panels.js": {
|
||||||
"sha256": "1af01633720865a83a10a1e5261e3738d91be310195b014e17e579893eae90ee",
|
"sha256": "33ed77006c3857a9eb93a72363a557ad87c425531e9d9d88eebc4bc8b4b28065",
|
||||||
"size": 267207
|
"size": 276124
|
||||||
},
|
},
|
||||||
"th_14_schema_editor.js": {
|
"th_14_schema_editor.js": {
|
||||||
"sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146",
|
"sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146",
|
||||||
"size": 20484
|
"size": 20484
|
||||||
},
|
},
|
||||||
"th_15_extra.js": {
|
"th_15_extra.js": {
|
||||||
"sha256": "f49d9e94702ff6b69b800aea10ae2d21dc0d52246ad176a92904a55352dbbf82",
|
"sha256": "2c4e560b793ee54f9338cc44bd41a056cbf8688560f9494920322c88d04be219",
|
||||||
"size": 122822
|
"size": 128697
|
||||||
},
|
},
|
||||||
"th_16_entry.js": {
|
"th_16_entry.js": {
|
||||||
"sha256": "6c59d9891cd010647f84c3db93f1cf95c7bbfb758470ea21044bf72eb8ff73d1",
|
"sha256": "652aa70214a9419923785e528a067d3828094fde48fc9c8c57cfda1e08206e25",
|
||||||
"size": 12799
|
"size": 12479
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyId": "toolhub-targets-2026-rsa3072",
|
"keyId": "toolhub-targets-2026-rsa3072",
|
||||||
"schema": 2,
|
"schema": 2,
|
||||||
"version": 20260522181206
|
"version": 20260522222851
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Oj/koe1KG25KEOTq/5jJfYFRBPL3ue9kSuhhKc7h0DGGpKJPwt0P1lmLCwJAKpIbwaQiuJo806UKW6r1qtHdjptDU0XreC8URd27lLWg1YgT61mVTKZK7qW8XSV71AebS51sHP+AmqAP9aiIdDRF1atUr0IX4+lxZAcN5t14aDLPwAqd0Kq5YJUUAjGACPbA9JuwjEwyXxlZ2NoyM2KZyDE983VlbJTEYUpvQYGZKKCSpPsowdNdz5OQMouDKigyLbCKQNva3+JtFfX4ZTzz4NMVJesBw82Q2MhlosCoAnrubhwj15MAYEMEP6TpajxjZVGVvFqCLJGh6d4lTq3i1RWPBGq7jTgIZPhlhUXSypt+v8TvWgv5UdmmDE+tSvPdNE+j8oLsah3toquYgiUcWnNaN2qdU9taa3cLb9JBOY1+mgs/M21yjYUC7A4WYpX7N4FPOqGLRUF0tPABBY1L6hY/gJ9YKPvvM4LC6e0C0cZThuBCJu/obk40Dl7iTcpS
|
Wt5bWVBi/YnfXYbb1pEQNWYaD0nbZ6QqW1NKp791UCjKV+Qlen6Tt9NNDYCDYwITODZAp3FPJfAzVkKawUX/ROh9u81UExKBvXGJJ5JQT9PwbrbP1JJ3oPV3CDFUTfwMCc7ev2c5R6hL+29CXEksRYXH+bqGW9fTvOAYeHsa8rRZTPXyAvH2f36XTuc7wXHvKpwLjmPZt68Ep4ICEJFi+wHZPS3r2qljsYFUmbSRCRPuv/E4pqVIz33vWaF3gepQgeNVAjnJ8c2dmQhjKiZ0wIOmOQqwNbDXjNYZNUrXoaPzJV/6OIzJRK8MyDWQbiWBwZwm3CJCZKfdI1qR1TGScInWOBBGhJ7IDilElGTHd6wwQsw4Y4h6KBqLaWT5bzxp2x+vRTXYYdc6RGR0yaauWVTqCCE2zf4Z6IfRNht/2+BZ4VG4W7WhEN72zdbPihfsJcxPUjQklN5gp3PScEI9PwymlecsDHOHmDSYFER3TUai3Uds7DQiTYjVxSTpce0f
|
||||||
|
|||||||
Reference in New Issue
Block a user