This commit is contained in:
Devon22 2026-03-12 22:36:07 +08:00
parent 927369f0da
commit 1a37086da2
6 changed files with 127 additions and 7 deletions

View file

@ -1,7 +1,7 @@
{
"id": "gridexplorer",
"name": "GridExplorer",
"version": "3.1.7",
"version": "3.1.8",
"minAppVersion": "1.1.0",
"description": "Browse note files in a grid view.",
"author": "Devon22",

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "gridexplorer",
"version": "3.1.7",
"version": "3.1.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gridexplorer",
"version": "3.1.7",
"version": "3.1.8",
"license": "MIT",
"dependencies": {
"@esbuild/linux-x64": "0.17.3",

View file

@ -1,6 +1,6 @@
{
"name": "gridexplorer",
"version": "3.1.7",
"version": "3.1.8",
"description": "Browse note files in a grid view.",
"main": "main.js",
"scripts": {

View file

@ -2329,6 +2329,127 @@ export class GridView extends ItemView {
console.error('Error loading note content:', error);
}
// 行動裝置下拉或上拉關閉筆記
if (Platform.isMobile && this.noteViewContainer) {
let startY = 0;
let startX = 0;
let currentY = 0;
let isPulling = false;
let isPullingUp = false;
let isDragging = false;
let initialScrollTop = 0;
let isAtTop = false;
let isAtBottom = false;
const handleTouchStart = (e: TouchEvent) => {
const target = e.target as HTMLElement;
// 避開按鈕、連結等可互動元素,以免影響正常點擊
if (target.closest('button') || target.closest('a') || target.closest('input') || target.closest('textarea')) {
return;
}
initialScrollTop = scrollContainer.scrollTop;
isAtTop = initialScrollTop <= 0;
// 考量誤差,留 1px 空間
isAtBottom = initialScrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 1;
// 只有在筆記滾動到最頂部或最底部時才記錄起始位置
if (isAtTop || isAtBottom) {
startY = e.touches[0].clientY;
startX = e.touches[0].clientX;
isPulling = true;
isDragging = false;
isPullingUp = false;
}
};
const handleTouchMove = (e: TouchEvent) => {
if (!isPulling || !this.noteViewContainer) return;
currentY = e.touches[0].clientY;
const currentX = e.touches[0].clientX;
const deltaY = currentY - startY;
const deltaX = currentX - startX;
// 如果還沒開始拖曳,先判斷滑動方向和距離
if (!isDragging) {
// 水平滑動取消
if (Math.abs(deltaX) > Math.abs(deltaY)) {
isPulling = false;
return;
}
// 根據位置判斷是否允許滑動方向
let canPullDown = isAtTop && deltaY > 5;
let canPullUp = isAtBottom && deltaY < -5;
if (canPullDown || canPullUp) {
isDragging = true;
// 當同時符合(例如內容很短)且往上拉時,視為上拉
isPullingUp = canPullUp && deltaY < 0;
if (this.noteViewContainer) {
this.noteViewContainer.style.transition = 'none';
}
} else if ((isAtTop && !isAtBottom && deltaY < 0) || (isAtBottom && !isAtTop && deltaY > 0)) {
// 往反方向正常滑動閱讀時,取消攔截
isPulling = false;
return;
}
}
// 在拖曳狀態下進行視窗移動
if (isDragging) {
// 防止觸發瀏覽器預設滾動或下拉更新
if (e.cancelable) {
e.preventDefault();
}
const resistance = 0.5;
const translateY = deltaY * resistance;
this.noteViewContainer.style.transform = `translateY(${translateY}px)`;
}
};
const handleTouchEnd = () => {
if (!isPulling || !this.noteViewContainer) return;
isPulling = false;
// 如果沒有真正拖曳,就當作一般點擊,不執行後續動畫
if (!isDragging) return;
isDragging = false;
const deltaY = currentY - startY;
// 判斷下拉或上拉距離是否夠大
if ((!isPullingUp && deltaY > 80) || (isPullingUp && deltaY < -80)) {
// 關閉筆記
const targetY = isPullingUp ? '-100vh' : '100vh';
this.noteViewContainer.style.transition = 'transform 0.2s ease-out';
this.noteViewContainer.style.transform = `translateY(${targetY})`;
setTimeout(() => {
this.hideNoteInGrid();
if (this.noteViewContainer) {
this.noteViewContainer.style.transform = '';
this.noteViewContainer.style.transition = '';
}
}, 200);
} else {
// 距離不夠,彈回原位
this.noteViewContainer.style.transition = 'transform 0.3s ease-out';
this.noteViewContainer.style.transform = `translateY(0)`;
setTimeout(() => {
if (this.noteViewContainer) {
this.noteViewContainer.style.transform = '';
this.noteViewContainer.style.transition = '';
}
}, 300);
}
};
this.noteViewContainer.addEventListener('touchstart', handleTouchStart, { passive: true });
this.noteViewContainer.addEventListener('touchmove', handleTouchMove, { passive: false });
this.noteViewContainer.addEventListener('touchend', handleTouchEnd);
}
// 設定狀態
this.isShowingNote = true;

View file

@ -599,7 +599,7 @@
margin-bottom: -2px;
}
/* 置頂分隔器圖示
/* 日期分隔器圖示
.ge-date-divider::before {
content: "📆";
margin-right: 6px;
@ -775,7 +775,6 @@
white-space: nowrap;
overflow: hidden;
color: var(--text-normal);
/* keep size; beautify look */
border: 1px solid var(--background-secondary) !important;
font-size: var(--font-ui-small);
display: inline-flex;

View file

@ -1,3 +1,3 @@
{
"3.1.7": "1.1.0"
"3.1.8": "1.1.0"
}