Add edge swipe dismiss for popup overlays
This commit is contained in:
@@ -4624,8 +4624,111 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) {
|
|||||||
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 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;
|
||||||
|
try { this.animate().cancel(); } catch(eCancel) {}
|
||||||
|
try { this.setTranslationX(dx); } 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;
|
||||||
|
var maxMove = Math.floor(panelWidth * 0.62);
|
||||||
|
var tx = mx;
|
||||||
|
if (tx > maxMove) tx = maxMove;
|
||||||
|
if (tx < -maxMove) tx = -maxMove;
|
||||||
|
this.setTranslationX(tx);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
this.animate().translationX(dir * panelWidth).alpha(0.96).setDuration(150).withEndAction(new java.lang.Runnable({ run: function() { closePopup(); } })).start();
|
||||||
|
} else {
|
||||||
|
this.animate().translationX(0).alpha(1).setDuration(160).start();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch(eTouch) {
|
||||||
|
popupBackActive = false;
|
||||||
|
popupBackEligible = false;
|
||||||
|
popupBackMoved = false;
|
||||||
|
popupBackEdge = -1;
|
||||||
|
try { this.setTranslationX(0); this.setAlpha(1); } 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;
|
||||||
|
|||||||
@@ -62,8 +62,8 @@
|
|||||||
"size": 23906
|
"size": 23906
|
||||||
},
|
},
|
||||||
"th_14_panels.js": {
|
"th_14_panels.js": {
|
||||||
"sha256": "fcbab7b835c4f020c258d8ddd81675e486572bc140dc6db4aa3bee3f9c2aa27d",
|
"sha256": "9ecfbb5f367802cb3b9f3cbcfbb473e75656207cd03ad61cd25bb43d080c8c41",
|
||||||
"size": 268044
|
"size": 272423
|
||||||
},
|
},
|
||||||
"th_14_schema_editor.js": {
|
"th_14_schema_editor.js": {
|
||||||
"sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146",
|
"sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146",
|
||||||
@@ -80,5 +80,5 @@
|
|||||||
},
|
},
|
||||||
"keyId": "toolhub-targets-2026-rsa3072",
|
"keyId": "toolhub-targets-2026-rsa3072",
|
||||||
"schema": 2,
|
"schema": 2,
|
||||||
"version": 20260522220033
|
"version": 20260522220817
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
C96vTXwZOxNzf6dPnp6DLtQzgY1xdVSe+JAObGu78cZqXO4BNCooFVfLGN4/WaTICx6e6mJ/dtmRVnPtJVc39+EDSaDWUg1ELtD4pPW4u5a5r8qU0J7mCxpUvLcTowG0txvheU4Cu5FQqPdHuBgNiyS1J5pNu0WAHapVBhyR7PXgOA8gnzzSaYZyawO/tf6uG20nVS3cFnlcw+ImvmY0tdLUTnfoaRJZBZMDAy5P36oLZCb3NSoqKPSrNj2cWr6i0x+h5D1jdDxRDjBGpK/fRsJAh4CdZTch8pEQsHVlGakb5hLmGARF0WR3RMHOCVeJNj2LXza1ktx2apjfUPJj84neHBgTCj0BcfwrZ0VY52cwE7n5aJn9xdXMaOiPzlioF7fcN9gmMS6ib0+N9qpW2sqfSSXmiWVEuUvNS0f11w39WfzPI5UNE+rt5bwplIWCuiLPWu65wAewm5Fz+y49ysqYuhPJwUEfJ8HLn+wRJnFcaOdWGod2U3DSVLliwi5Y
|
YhHLAiZPsJLqf7OEX6ttGyJW25rDDxh+lv066wwRbJMIVsvbpX5m0NKmXTwTJhHYrwc2G3Fsile9hvTe6UXXEQU8FurBxA55g3U9WQadSsXVBi2I3E41IiES5IiFxpp1BHDXr4X3mOv1tvNmAfiPdVZ9NU/YD8+gGHdcGUK/OT5DWpfFduTOAdkC9garVWdfHPCxHlxwCS7TYoeKxkGdi8gQdR/pWHfRp6F9pZ103HyuRyTWCZVeU+1Nh/VGOb5a+HGPGQmHOcEb/Gqh4+w9AuGH++VhpH50fMJJdh5CZVObuTlfsEnili+F0QmHhMeKhzpnPnP2gj15ahAm0ThK6rOgDxdyeJ1DzptbkhjYAckoTMLcDEKulJ24fiugkPIvL1vx/OR6mqM8/JJKIA/4aFe+Km1SRLNj7c9m6VOYGQypA6PD2qwDdreMm2AZzyhcIEQdUIbH0k8lFUPFrVVRBAYgJf7R/SkTeLvHgeczPGsjX1nadPavl+4RsrLpLeVi
|
||||||
|
|||||||
Reference in New Issue
Block a user