Skip to content

Commit 9c93fde

Browse files
committed
feat: enhance PullToRefresh component for native platform support and improve touch event handling
1 parent 24c68da commit 9c93fde

1 file changed

Lines changed: 48 additions & 39 deletions

File tree

src/components/ui/PullToRefresh.tsx

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useRef, useCallback, type ReactNode } from 'react'
2+
import { Capacitor } from '@capacitor/core'
23

34
const THRESHOLD = 80
45
const MAX_PULL = 120
@@ -10,13 +11,15 @@ export function PullToRefresh({
1011
onRefresh: () => Promise<void>
1112
children: ReactNode
1213
}) {
14+
const isNativePlatform = Capacitor.isNativePlatform()
1315
const [pullDistance, setPullDistance] = useState(0)
1416
const [refreshing, setRefreshing] = useState(false)
1517
const startY = useRef(0)
1618
const pulling = useRef(false)
1719

1820
const handleTouchStart = useCallback(
1921
(e: React.TouchEvent) => {
22+
if (!isNativePlatform) return
2023
if (refreshing) return
2124
// Only activate when scrolled to the top
2225
const scrollTop =
@@ -25,11 +28,12 @@ export function PullToRefresh({
2528
startY.current = e.touches[0].clientY
2629
pulling.current = true
2730
},
28-
[refreshing],
31+
[isNativePlatform, refreshing],
2932
)
3033

3134
const handleTouchMove = useCallback(
3235
(e: React.TouchEvent) => {
36+
if (!isNativePlatform) return
3337
if (!pulling.current || refreshing) return
3438
const dy = e.touches[0].clientY - startY.current
3539
if (dy < 0) {
@@ -41,10 +45,11 @@ export function PullToRefresh({
4145
const distance = Math.min(dy * 0.5, MAX_PULL)
4246
setPullDistance(distance)
4347
},
44-
[refreshing],
48+
[isNativePlatform, refreshing],
4549
)
4650

4751
const handleTouchEnd = useCallback(async () => {
52+
if (!isNativePlatform) return
4853
if (!pulling.current && pullDistance === 0) return
4954
pulling.current = false
5055

@@ -60,61 +65,65 @@ export function PullToRefresh({
6065
} else {
6166
setPullDistance(0)
6267
}
63-
}, [pullDistance, onRefresh])
68+
}, [isNativePlatform, pullDistance, onRefresh])
6469

6570
const progress = Math.min(pullDistance / THRESHOLD, 1)
6671

6772
return (
6873
<div
69-
onTouchStart={handleTouchStart}
70-
onTouchMove={handleTouchMove}
71-
onTouchEnd={handleTouchEnd}
74+
onTouchStart={isNativePlatform ? handleTouchStart : undefined}
75+
onTouchMove={isNativePlatform ? handleTouchMove : undefined}
76+
onTouchEnd={isNativePlatform ? handleTouchEnd : undefined}
7277
className="relative"
7378
>
7479
{/* Spinner */}
75-
<div
76-
className="absolute left-1/2 -translate-x-1/2 flex items-center justify-center z-10 pointer-events-none"
77-
style={{
78-
top: pullDistance - 40,
79-
opacity: progress,
80-
transition: pulling.current ? 'none' : 'all 0.3s ease',
81-
}}
82-
>
83-
<svg
84-
className="h-6 w-6 text-ink-muted"
85-
viewBox="0 0 24 24"
86-
fill="none"
87-
stroke="currentColor"
88-
strokeWidth={2.5}
80+
{isNativePlatform && (
81+
<div
82+
className="absolute left-1/2 -translate-x-1/2 flex items-center justify-center z-10 pointer-events-none"
8983
style={{
90-
transform: refreshing
91-
? undefined
92-
: `rotate(${progress * 360}deg)`,
93-
transition: pulling.current ? 'none' : 'transform 0.3s ease',
84+
top: pullDistance - 40,
85+
opacity: progress,
86+
transition: pulling.current ? 'none' : 'all 0.3s ease',
9487
}}
9588
>
96-
{refreshing ? (
97-
<g className="animate-spin origin-center">
89+
<svg
90+
className="h-6 w-6 text-ink-muted"
91+
viewBox="0 0 24 24"
92+
fill="none"
93+
stroke="currentColor"
94+
strokeWidth={2.5}
95+
style={{
96+
transform: refreshing
97+
? undefined
98+
: `rotate(${progress * 360}deg)`,
99+
transition: pulling.current ? 'none' : 'transform 0.3s ease',
100+
}}
101+
>
102+
{refreshing ? (
103+
<g className="animate-spin origin-center">
104+
<path
105+
strokeLinecap="round"
106+
d="M12 2a10 10 0 0 1 10 10"
107+
/>
108+
</g>
109+
) : (
98110
<path
99111
strokeLinecap="round"
100-
d="M12 2a10 10 0 0 1 10 10"
112+
strokeLinejoin="round"
113+
d="M4 4v5h5M20 20v-5h-5M4 9a8 8 0 0 1 13.3-4.3M20 15a8 8 0 0 1-13.3 4.3"
101114
/>
102-
</g>
103-
) : (
104-
<path
105-
strokeLinecap="round"
106-
strokeLinejoin="round"
107-
d="M4 4v5h5M20 20v-5h-5M4 9a8 8 0 0 1 13.3-4.3M20 15a8 8 0 0 1-13.3 4.3"
108-
/>
109-
)}
110-
</svg>
111-
</div>
115+
)}
116+
</svg>
117+
</div>
118+
)}
112119

113120
{/* Content */}
114121
<div
115122
style={{
116-
transform: `translateY(${pullDistance}px)`,
117-
transition: pulling.current ? 'none' : 'transform 0.3s ease',
123+
transform: isNativePlatform ? `translateY(${pullDistance}px)` : undefined,
124+
transition: isNativePlatform
125+
? (pulling.current ? 'none' : 'transform 0.3s ease')
126+
: undefined,
118127
}}
119128
>
120129
{children}

0 commit comments

Comments
 (0)