From 1a37086da2482999fcdee327e4b1778237ef2779 Mon Sep 17 00:00:00 2001 From: Devon22 Date: Thu, 12 Mar 2026 22:36:07 +0800 Subject: [PATCH] 3.1.8 --- manifest.json | 2 +- package-lock.json | 4 +- package.json | 2 +- src/GridView.ts | 121 ++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 3 +- versions.json | 2 +- 6 files changed, 127 insertions(+), 7 deletions(-) diff --git a/manifest.json b/manifest.json index 6972727..1f2db02 100644 --- a/manifest.json +++ b/manifest.json @@ -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", diff --git a/package-lock.json b/package-lock.json index 9ed4aae..e548a20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 21bb7fb..f5f4214 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/GridView.ts b/src/GridView.ts index f05c01c..fe1820d 100644 --- a/src/GridView.ts +++ b/src/GridView.ts @@ -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; diff --git a/styles.css b/styles.css index e7550f3..7b1551d 100644 --- a/styles.css +++ b/styles.css @@ -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; diff --git a/versions.json b/versions.json index 246d8d6..21e03fb 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "3.1.7": "1.1.0" + "3.1.8": "1.1.0" } \ No newline at end of file