328ad632d3
CI / test (push) Has been cancelled
iOS standalone PWAs don't get Safari's native pull-to-refresh, so add our own. New <PullToRefresh> component handles the gesture: dampened drag past an 80px threshold triggers an async onRefresh; below that it springs back. Swipe direction is locked to the first 6px of movement, so horizontal carousel swipes (landscape Home) don't accidentally fire PTR. The arrow icon rotates from 0° to 180° as the pull approaches the threshold and turns primary-color when ready; during refresh a CSS spinner replaces it. - HomeView refreshes the device list (and sync status with it) - LibraryView refreshes images, pending-share count, devices, and the active shared sub-tab page when it's the one in view Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 line
2.1 KiB
JavaScript
1 line
2.1 KiB
JavaScript
import{O as e,V as t,_ as n,dt as r,j as i,l as a,p as o,t as s,u as c,ut as l}from"./_plugin-vue_export-helper-CeYnMxKK.js";var u={key:1,class:`ptr__spinner`,role:`status`,"aria-label":`Refreshing`},d=s(n({__name:`PullToRefresh`,props:{isAtTop:{},onRefresh:{},threshold:{default:80},maxPull:{default:140}},setup(n){let s=n,d=t(0),f=t(!1),p=0,m=0,h=!1,g=null,_=a(()=>Math.min(d.value/s.threshold,1)),v=a(()=>f.value?1:Math.min(d.value/s.threshold,1)),y=a(()=>({transform:`translateY(${d.value}px)`,transition:h?`none`:`transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1)`}));function b(e){f.value||s.isAtTop&&!s.isAtTop()||e.touches.length===1&&(p=e.touches[0].clientY,m=e.touches[0].clientX,h=!0,g=null)}function x(e){if(!h)return;let t=e.touches[0].clientX-m,n=e.touches[0].clientY-p;if(g===null){if(Math.abs(t)<6&&Math.abs(n)<6)return;g=Math.abs(t)>Math.abs(n)?`x`:`y`}if(g===`x`||n<=0){h=!1,d.value=0;return}if(s.isAtTop&&!s.isAtTop()){h=!1,d.value=0;return}let r=n<s.maxPull?n*.5:s.maxPull*.5+(n-s.maxPull)*.1;d.value=Math.min(r,s.maxPull*.7),e.cancelable&&e.preventDefault()}async function S(){if(h)if(h=!1,d.value>=s.threshold){f.value=!0,d.value=s.threshold*.7;try{await s.onRefresh()}catch(e){console.error(`Pull-to-refresh failed:`,e)}finally{f.value=!1,d.value=0}}else d.value=0}return(t,n)=>(e(),o(`div`,{class:`ptr`,onTouchstartPassive:b,onTouchmove:x,onTouchend:S,onTouchcancel:S},[c(`div`,{class:l([`ptr__indicator`,{"ptr__indicator--ready":_.value>=1}]),style:r({opacity:v.value,transform:`translateY(${d.value*.6}px)`}),"aria-hidden":`true`},[f.value?(e(),o(`div`,u)):(e(),o(`svg`,{key:0,class:`ptr__arrow`,viewBox:`0 0 24 24`,style:r({transform:`rotate(${_.value*180}deg)`})},[...n[0]||=[c(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`,stroke:`currentColor`,"stroke-width":`2.5`,"stroke-linecap":`round`},null,-1),c(`polyline`,{points:`6 13 12 19 18 13`,stroke:`currentColor`,"stroke-width":`2.5`,fill:`none`,"stroke-linecap":`round`,"stroke-linejoin":`round`},null,-1)]],4))],6),c(`div`,{class:`ptr__content`,style:r(y.value)},[i(t.$slots,`default`,{},void 0,!0)],4)],32))}}),[[`__scopeId`,`data-v-e2242f3c`]]);export{d as t}; |