From e0a61c074ea9091cbf3cdbf357225289b16e2b17 Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Tue, 23 Jun 2026 06:42:04 +0200 Subject: [PATCH] Use pointer based internal drag and drop --- build-plugin.sh | 2 +- packages/u-navigator-2026.06.23.r001.tgz | Bin 11857 -> 0 bytes packages/u-navigator-2026.06.23.r002.tgz | Bin 0 -> 12528 bytes server/public/app.js | 164 ++++++++++++++++++----- server/public/styles.css | 18 ++- u-navigator.plg | 4 +- 6 files changed, 153 insertions(+), 35 deletions(-) delete mode 100644 packages/u-navigator-2026.06.23.r001.tgz create mode 100644 packages/u-navigator-2026.06.23.r002.tgz diff --git a/build-plugin.sh b/build-plugin.sh index c96a11b..bda7840 100755 --- a/build-plugin.sh +++ b/build-plugin.sh @@ -2,7 +2,7 @@ set -eu PLUGIN="u-navigator" -VERSION="2026.06.23.r001" +VERSION="2026.06.23.r002" PKG_DIR="packages" WORK_DIR=".plugin-build" PKG_NAME="${PLUGIN}-${VERSION}.tgz" diff --git a/packages/u-navigator-2026.06.23.r001.tgz b/packages/u-navigator-2026.06.23.r001.tgz deleted file mode 100644 index 8bb9ee66d55fca5865d68058999ef048188f5d8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11857 zcmV-XF0RoZiwFRL4LWK71MPj=b{k2OSnr1V8}1i>4%Yx3+Z~ zk?NivE)5ld0#U6(6{e~nimm0VAAF8q*Y?vMpWSa*zq_CO8~Y`Wh`iSY7fM3UN|mS8 zL}leAGBP4EA~G_o-kV0@7aun@8jbBv$D+So_P5b$v%l>3meuUEn%#Dz+if(hMzhu3 z-ul97d}O#NO{3Tj0hF=(+UdDlJKdaeP;5Ay(GDAmCI9|gN&oIY{rfNe`in1~*nR8S zsr5&TC(QfeKfu2h{QEQf!{>imtjXiEvlsj)*7%?B?>{Dr{FTc8n|?5^+mngs)F)x^ z#_?^x?|kuBfBi-L-^>5x|F{3Q^#KN1q`dUpe*3Ls51erG=!{NLD4@PE7A+Wx|N z`;p)=(r3>9tzByzyJP3DxxLeB?(DYP&H8q`z17~`-C65wTaO>zKYsDx+ehD@)Zf~1 z9M-eA_3-!)kB$eA8bQ$Nes^>BWUakxokFF@KhCP8vH04rjfT%Q0oQMS>^|o4Kk`dr z{qJlwzpy$V8!$|tIsfDQ*Lz;jx4nH^1spnKaL!j%m2-! z{O@#{TZR6&inP_p*8g^4T3Uqy_{k^af8zR&s0A*s|7~?!TZR6&ilpYh-gCyIIG%j? zK9<-2I<0QE(EnDF3jOc1PKy7P7Wkp%!1DUvcB9!Y^uJZ49R07|+U_pzAXxV-+?X|~#h{MatIyc6K^j+q>OD|NG?ALj3<; ztN&d7-|BRe{{J?`{}${2$4^fje|orne;UVuAMNe#uCJZBvF9AFYjeK7_NX8DhwCo< zzc#H60}qyh^|c4V0Ll#;+n4KWwOVcMAnJ$iB)+#+E?2C>d)B)(%YqtFYypO^ocP<& z8Cr){Y4a=yyhtai(te`one#TrqEP1e`$yj#pFMj4WuVY->i1(e@GUiR!9{rII$ z?PbxnJG9D!pg$cueq8_a)Cq4+9S=$eVYy_Vk6>_z>*=AbUsNsod|=0RP2(v1b+{gf zQ)m66R1rN0`1k3FAQNcuT>o_h7&))k>)AjYdmg}1s$A@A)nWwaG1P^s)I@#g`h#*A zf6F=2iZiq;++w*p<~|7g7`m+N8|6oAMyV9c+A&Ca_i`FLBD*x=+v&W~D$2vHaM8n&T?=jV^QGpfJ>K$2fmiwV& z#}4nZT=HDN>t60_pn&}Z-7MO&O${R~tOc6ZzGp`f16)Ic%GG9=%5#!X9Iw682uT(} zPS=V=1{GzoO{r>?ka5H~6_hx{dgzQnzktC2L%(sba6}B^4Dfg0mvqumXi=nt<2Obv zCNOi%dijO>*D7Mu{@}sL^#+V74Vpz5adAf31f&;_d_h49zY6li^ehREF-)v`v_$2^ zB-n$2tX0WI)KOL;K5PLBs3A@m9}j-A`-3lRuxQ;BgyLIZ6NZcbw$aK>_8 zU=LtXC<%PYf&j+}XrwVh<@gRr^M}u#a58-im1wjX3j^!da=ge9D@4}n!JxaX;ID&C zu|)pb%f3v@`+t^J|L)@dX%+EbD@uj`=d(_C_x~&|2bTB$bhfuUh5u(2DQEw0tJ`RI zi}?RfKP~J3S$_4O%m2+zyOUi18|_B1{;wi2{|_10vs^#S=Ti&7TH(%~qvzi~U)x~R z0#?$xMlb98Ye)Ci4#@Tl9q({Gif=q88aYn9ZgEG6AhUy`L*B^Iy-lzUoH*KK#q0ej zT8Cx^?i-8DhC|ke1#+YYjd>otwXA~?txTdw9850lklw&MsC$o_9|xo6J#AnIoA4}N zO)PhSP}=b{LW6Yu-Xq_QUE6ab7fg+My?(Gc;Z1JJHV+UO*=^uqzm^@kcFnUdao9fu z;p=Du#*1Z>dnsC%JzkQ-jk@)n>yx(=F9@BGx#8BWn9YO8wgP83^a1ntM9#q`Yapk+ z=OIi~7`slCY|*`P{HQ-d6Ux_`)wAcc{fDVDbrQ{hQcDD-q@6%5U@jr0=`^13G%!q}txGkLC5hR;N+i|G1h|=zpJeT2}wNiyT;9|7*9liu2zqN!j|} zb{nRkSzG}A>8Hi?KjzrFYah$&f32-{asT5=(lYa3?wIRCSnl%xM`H+CDl#rf|~KP|)mcU%4E@qe@3>a>#Uf4fnv z|0_v#7E^%%%(dF()t>d6VSCse?(9=WG!2J#-@#l;MsBSI`HnMe4Ld9!Iys^2R?oiZanbb>bXWQ=bUZRmb2(I@m zSTlAeZ>>%T{uf?d+T~WeYHh*4cBg7J>a7-qUSHb%*H>XM^#O`Ec38$iR@iYPF9<~* zogu>9fg4Rc`)1F&3S9zY7$98D_T=qmv);C%n<#e1wW(XRY9!BUET?MS$8Z?MJo930*=WHV?gyp|jYjg~4^SXW7#@u$sdV-;Z6tHgepn z5p)jB*)KO6jW;8!W;M4PleYls?b_OZ9y1 ze+0AZ&5Z0Jv3}kNv%c>YV!D9fxc&U=ESI0wrRL%C>E5C*(Dqs*; znt>-d!u4^)wV~$_L=wUVgYYL1r0(zrx}}p7dK1Qg8p#3S)3rN@M`E-J#5#-Sng!k> za|croLmkhULODn=x+{AE#k)B}qd=qDr4wH}j&F>n2_xY3(!&@v`I*Qp%0Mzek_BEt zmcT5+w?G_8%CQ~7;*3<#u-e(3Oe90pi67HlQg+2?F3}LhvQfnpV(@Pb59sXCF&&Ak zodh&8WQ&^7DS##%iFN3q1Q@x40Y_pGxfmw5he3ljo(nQtr0}hez_1+KBr>>I;*HW% z_PVf)0B`MZqQ^{0>O5~YChSWX0nAqhChEhWKaKbVn>^1}g0cIy?D|#&a>q$NlO;{fllSH$X zoT+wFI^nuR3ly?7m&Jf|SZ3)Y+@9qJzLSlLC=LVviZGHj$H@3K^}_KycM`b~Ny8B! zuSVR19WXvi%}OfHiV4JB6Z6OHJCWVG?Nm>=-*uX4MJ)q2uX=QLDHN{XOv?tb;Qcfmx1+l zeME~4h_}FplpGPB@SMX$cOiBmme>zT_9XiiyCtVr0OR_TX*^r%8Vvk_6s2XgqFn>C zpe_H_7|kFICbge|S2YS@kPhr<1R^fRP-S+yJAaALVQB6oF(&(fU-nf^>0=t+=1S(~ z4oGGV7#(rh8l8Mi=J_5&eR4s=qqH%p4GkjnT&=J^bit^J?Mu%|EG(Wqi5waM{hF_Q zWlwD03~BwwqiSaMV9w%ied&%TK^WV{9L`@*Qg9|3l4OP}!8RiW65qt6dzR-6soWck zxd&@a~|i8C8tD#0#D}G`ml;GB)yGQdMBkEHakh# za%m5)(z0t2DZ9J7n;~Zv_2k)i8B{gL#N)tsb`rw5#dIiRJk$hm(Ae>(e<>=xJ^{N) zMX)<-b^o~rik0)0q*^1vZN^A-r-LEW6U$Eu(`0s`r!vkHK6!FAqkr93u$WSA&<;ns z*2kam*bn4Kv8jw2N=iz@_$j!&6GbQKE3LYO!4+tS(J~`Uu}ea&Hq$?0q)8|CM^tbsQJ)woVI+cT9yFzy6(Ns~3x8=&_Y=Q|T}YA}JS zwXD#_y$H5{a}7$KW4JUCI*x&DG?WcTrtTF=h+30PxVK{9hEAU`EgL?*qYFc_ofTPT zkXf9}sA?)FVKGbELKfwN&$6TST+QxLG+{b`89q$Sz_NHBseDbS@m90kEbRK2Nmc`z zTuHpkz{#E;#AV@_kT=1sGv|RiTJKDHxAIr!8Y<0Jb`0v%E zBL3&IPIrs{SxyctAOF*7w~F}hm89(WpH8#gY8Bsq{S4AF{C~IAe;)sLnp>UJ`QLW8 zSpQd&__e6g06Mht?zsJpEQHrJvU=*ulvx#3DOFRufFtu>4!mO%&z+X^t`IzCf%-!i zEPsFMc~vr&u?4WE&M&Iux+44I(Lj|D4!{#X4sTR8caGpCI4YCefvKWD1((o)?_66? z>`A$TSw2+#fx5=7nwa(TBjyNdHP&wT*Er}HVi9rBnK2q*%cZaBQk@ck?4s+w^fmmU z=jdjP@kEe?7kW}w5RcGHQo`#>OVoNU!c$kulqwn5T=qS;4^3O_wr0HAM^q}~hVZP` zlNZb^*uJVZw+HQ-nFSlC8r1HZ>$@@Dx4C9VH-2Bg-Wl_09$;>{u}OqgXCwuaWMA8E zYyst!;or;9gRbaReKMMqD*U2Sx_4NwSPz3Bj*jY{<6p%i?M~JaI@*zHPQnn!_B62c zYip<)r{`(t4Af1i0yM@riMw-OZM;kO&O5)gUcgh;N)`dl?V0c0SVvar1^liB@KCaV zpicXv&~Yz+o?eCSaA?`DWA{zz_7wxfAd7UL=Zy>6DXgf{`XsAdK09R0TYWq3kF2tT zD5+@EkU3T=RUbQ1WM4^Vz?z&>13;Hu+w>eDf|@$GM`DHm;v)t!bxbpm#u;Z1wj{5yhcfM?Q8&$(2 z)D{^iYTDLUe5hOwaze0v5ARs98hit*O)zU4hhyNIMcOT$f-zW_wQaHY5noKJwXszX2}IC|mTeu@%w;-i7^!U>$~ z_gx|4mCG`T`gSXU`mL5ieN#*W;CI)=p%_pSK+XsGu*o~K5H518r$A~aL27H%&`}^Y zx8}oSbWX7=RqHi8RRLNGFR5tv_`3s?J%IR{5H9)>_|;cTXy~-g0Cxur4r-V=8>uG& zH1DeZR)Q{aZmRmoMJ_#>I1sPcGkYi9u?F#pCHkwc*bvyWjwsO}^}?qb!LA7DghEgXOQ8@g(%1u4yeyha4@~P)BPPewb;iV9^bzyev*pn7j0@Rc z@kl^HgBs2cNt>(#ox&=|^J$GM-9mAErCjt-LO$>^uXt}1Nl{0aI$LX#6&p|-^WNT0 z-kNpdU^2VPO{xkJb9N<#dQf)&FF#OG)(}-oHO9z)vDUt2Wm$8qVyZpH985{)5Bxnc z2Uvxi^oZaY>iPS$%En`!p|md*H<}}pBqf2!NVzDtLyrYrd zbNR}^-P~Dq-cT45Of7B0Jp@~dPcOZxT2k=HHWS+ac{YMBW}5-3UnaHa8HhNTph{q0 z(Ki%?LTaM*(E8HI;9G|Y$`q=dlIFKd41*#5Lyo}^{8HH!OB2|WFe&9SeINl_q^~c4 zT>MgsNTVHn-7;IU<8rN8Il{WI6bhX-jS0!N6kWOi%VIf`UA6F3;#gdk5LQ$h*hd_s zf?VPKOHC0gG2+UuscCqkuBIzu?VO5C1rv3c`X-Ch7}7Hu^~1pPq>y_jZANSw>7woh z{nw{dO4*9k7^`|l%Sc9Pd;!zIw{nd-kJ)mSQHkE@wam}s2#%mydjBRs`&k8frwK4L zn!uHS)P}NPl&U4s7dn95C_eVxG12zdAy7hDM_N8kq6~b@z($nD#I2lhlmEqxFmh)5 z(~A(a#mkyRZR~HCjB?8g(-%}NN1SS?78)9smO38SJsmGg^~_)+O;aO1Sm9C&=sw^relY6gNYi3*A0LN}qtv!a}@Y}5s5=IQ@ggnC#Ro*_c z_7UCZ7nR$TcA%_7nlmm8600G-)8zil#S&&{&Pqux3XUg|_Ol?D3}vwOD=B{44A z9nkyTdSbDG=mRNho$Bi@65OAV-m+&vg{QM=5XCcKLF%N)&Mc(_<>knZ9zyl!_6-8c zi>QT+=`E9x{ytO$EL4$>Fa6|0`iZrb~6AF9|B9jut4v@1UhD3 z_#E{%8^0d}KHbZ2amPMehjHe#6;x+rj@(QiHO%@bxMrSw_F{>t;I0*n!_8Orv$27_ z>aG?Ya@5FmC0uh6;nqVi%#a53tw=@)VN{YSh@Sfc zG$dm7Vr~G`RfW7`IxCZUq$$p9&6JzW4NW_DtN|L!BJB(=J+mn><0vSom3n+L;op*z zn|LKf8CjldR!_r-P`7Vq!vbVX3SSnT2#ZbMr9?+7ch{>ffi!Hq2!Q3_@2V9A)3EQT zJxlH^yVZmm6KFso!L=h~qO=uiUvOmX%Y7!2&4zV$*4rld&fKvROyjcI zKn_-vxeAa~t;WJY<}Dk`(8KKYV~%gN z01#v0F%Qpi!n*YkSk85P>-8`H0;ZsEja+zbUtYn`u43yNguLT38nWGp}GBTuY>^&@AWSdVeN5#7Odcab&Z*GjpO#UeWpCH&jV%+SN)2_sXZ zF=d+_#DjYW(ZrSxR(a-Y-OQ)MT4<_K;K#XQp$oEEDS!i=$xy|#=ai_fi1!DZ(5nW3 zzyLOPJL@HrOo%!Bg7FYP=^Wp`iJge|Le2q(m~=B3uz-`x%Z`JAJ9M4Fag1NkevIK_ z4*$k>MXL?J=uG>}ho6T>tXVBQI9Gr2FuQuaq}ctjNk5;|*U)nW{otR*L2R?MO9bWKGfvhH%EK9Ho& zkd{d-nv+>0CzCoeM z3W(Rt>0lv*rMeHix4+77z{R-b3 z+}9cyI8h8ZCInFsfAsnztE)!HcSFXI*iujjJQgWxgJQN zsXws(|Rb1*Zqqw+bk zv8$PLW7^{vNd(WDdDNVcJ+7FMIB^E3@JE`(j@YD9i8X}Rhcy$$1fcM1_z6p(EsPV* zg@pCdheYit^kZeQuSYs2Myugp_J5`$q%l5pfNdX)oc?QPAZ5vPf@oVxnp7nqV<#R3 z1DL7j&rZ)uBDxS4wmkyUF!LA?GsSEkvnyJ`wM#fss%hesYkj8Nq}2lk%C`fuhf0g1 z8f4ZG*=IAOJ?ouS;-RTE(7>D$6vJaSZl6Hf{3#0jl66~MQ&{=i(`Qd%y+n=19p04R zWeo)|wkFV~=_-*E^HsWvBc#`p!1E9-eDyZhlr$c*dBhzUVTM!R1?A(>Ama3S3jJb{ zeOZFdSbo?8ZD4|qk`p~({qA>GS@u#N*-@FtM4+JjQoSKHlKN$H31-09jT{ga9w$kz z6p0Sg#APgbl}aM~GII+;4-Vy`pq$~}0#LJ=U+}xxRnirrAzWxke9b)4RVJ?dD)$Ln zuXu?>AKCCE0`B?9P!Z;m7x5z$)}uO;Y;3#nLSOIA>KAFpM~?e4(SN$nx}(=Ztr}N= zCn)@l{!_hWxaa6;fi4HKDx#f!q{q6sY28O-)d^wPKk+MUMve%afG2hrk2QiNYM)-w z*OBS04E6y0;d&km{j2B5HsDtf*C|hwMjsgE%i|e9_Z?3_9e4`HL1{BiFf1yh}sLr%(2mJxNIfvQ;sGKG{Z&>Zd4S zc}yB&ZMLIS!(zzTO+~^2eE0EA77%d{C@A&?^0Kz@X#vqPoc-+{XJ{5j`$wxr4O76d zj9}MG{3uGq!9)bK`)dD%Wf8E?)h3S8-1#Yq+tlKk@H-gM*oJr~;O7P~VL3B+NxwX( zB#R`&qf?ktfzeud85*4~&V!=Y%(DZ@r9Hg?=?*j}u-+h{SJM}Sj}G#W4EyqE_Qqzq zWjRX~JsgttA}-`Sq{V4X+dvUawCLs$Z;72SI4|*Vr5WKNnuNMA6>qbpmt&9sj;}YC zBmPA*i3SV_11q>}W`-gNpzbnqS_A<7QO}VD; zlj?pCGPN_d=GeehnfwhnwpJUin4C>G5*2y?BO9HXi=540hIIqj(PV zd@Eg9DL8kT3J$jp-N7=}u{+4NjL|#HU5N>+RJTa=IYrE!vk-0!Iw*xx-^YLglu396 zh1Zjsbm>AVo0>~mo(D}5pEk6rwcTiB?8D|oqp(=y`z%hL;&)8%u6~%(I@Dyl8o9B} zB+BfsWglCZPM}%mlvjCy7PpqKwzh;h&e0gbqU2;n?-vwBdUoNRK|j+sBMnL!PS-Ll;r`jsw$K|)nuNRP-l6;@Cung z&H<6VYpzU>buE!nRu3x;8WXju`#F*$&&V~;tfU9t~Ce4+zS%tJhHZf%%dY&XFBo@jAWeZFinnJ`JjL#Q&Pvn$HDil*_AL=mGM05 zIL*;f)}a!}Z79v&n|-z>-Gs>2+TaLF=qRZJF0nXilRnHMu6n)YOE0x2q;=Lw8eW90 zm}&vz*&-e;N3Sy4&!abOzw9F%A*$kSmq~j+|5%|UIi@Tz_d}gjok-KW(Qr!~_)*S{ z{Fp9z4NV9Z|DovtNWA|s@%~5kJ_y|_*Z(6Yrnku#Kk^qh>IILNrInLICvp_Pe7QJd zLxvfB&dNNnConRnEUV}z22fo^a+GSTHv0q}URL4R<4IXS{goxlYR(Ua6Z&e?6Wr(n z#Nv0HvQID54W{~j@J*tZA2WLSQS|cT++O&p=9;zBQ2S@vPOd`ibdumjCReicc#c5s zC&WK$2=gjUG0Ji}QT_8exv|m7Ugnio9i%uV@5~qtIiJ{P1TTI_KKOy3eZLk5+LHyo z73bNn{cNksIB4~|9<*|C%Qfo)H#9^F8wVx#+CTu~p^roSgd9etr zHDKeB{hP5{$8FB+{l@%u=JuZMmQ)PcY4BPoHJ+nyp}pF8C(AG+67QZ! zWZ}g^BI-eRu&8FrBB;O^V}(bzz!IhfwisJf)MO$&LifDfrV(h$jqAk42Xa}>*-cG^ z55E#BAq&PbLw+a@g$-PT1Iy6yU=tAS%o{t?r_C9>qy1mLJxT9*gx8FS6)}rcTikzi zaA-A!3c!w>YBct0bK@N=9eHlw!4;?06!Bcp!)+o0P;42k3}C4B9^mSclb85^9b^XM zp~XYr=sktJNw8Rn1FP9+wIxKr0F-}g-G7x;(E5F>Ca7t4%$lyRjp)+yu9(?Djem)0@sH(R^=C1kkDId*hW$r=KM zy{Cte8eih}DAL>LO%<=2ui~9cMgwxeq_^w|Xc2O%mOQAdH_4rW>V`HoP2zIMobAMk z5oGpX{%(`MqAB~e@7erIO^eXUoRiy0u-)W*cTgCnFpL|-F|L?r|&*%TLy=>JR0fjj8` zt#+f(|5uT6^#69Zx!r0O`u``N7Uusuul{rSzXcXRa{X_0w~O_E6=^B`eMp{9=h^N7jaZ`V67l@Wtu0 zQoV#*TzW>`xYY}T$z5OE*T}Y8H-=M+hD!BGI4r^csXbO@gNOP9Lhut$WvX1E`-<2{ zpYXs|S)fb4RO9EbF-%i?&u;qJvr6=xDEXx#fhHI@AWDv+gz%72Mvzt23j&;847IPg zzzYPMy`aNh>IDXv(2EpMbdnR^ikv;Gq197Ytx#D|-;SLActVZS6kSxQDfSyFzmjE#t4T{zAUDD}dRQ5OtHJ~? z(h~N+x~O5vKJK#rhu?oK*8dfx!v6oP(;e*prRBg~_WwG~!v0@H%CY}Nk;l5*fq_Ft#4|5lN* z?Z0MgcWZa6UD$u0d|D#@^Ny?kJpOMsx~)|FXSdZT*8f!`X8*0R1Ai}{9)I6^c=Gk} z%g1NE7tfxZ;f-XQV?W-Ug3X5(pt`U{i{;$2>@c*&A=V8RDLf6y_yX(0@!yn7FMHTF zws~42WjNIrH*2U(Jc)}<_W0)!*aJTs$sX|9-BKL7W4yK#Pn-^%a;XXrTK|huiOu&eyp~{E7n(5vr;aZh!Xl@sB{Fv}@ZeWi&}f+s1@l*-V$igJDRgx?wh2jRth|CU6J5BNVDV zanQPlcbb)XX+9Komv`B?$9vC8-r~J);n~f|i4Ujou(l)c;PgjjE!fWgC5UaHzj*uIJ(~Vf>3L(`)TX&OWV&GzUrhNyS#A|tZiLKGp4 zE34=nsW2Z&7Qk4h2TYGNB4Lrn=N1%oamGsOdrD1i*dSFC8Ji^Cv%D3oTp1ZTAy zTUsER&OiIIx3?!ypax?MB zBqe(@%W?R`jUsGBYdtZtG}bwS*`*42Jt@DbAcbLG`F`s>n zS8<{L7S^*~pDiR&xdf`+-sYzE?QL`$vyZvcnlW(Lnt=@fPnO=@g8qc^Q`ee6G*NG5 zs+vDEq{~M>C~SZkTzlw7uk7`jeMLSsNW3N(Mv7P3yKmI8AU;qbp7n2Tq-H`!)v;Q$ z!F>Q7Vv{`ZE|SrPOg5%H*Fr7JXq-8=U(;(1!m8ES-rnX|Ma@obdFaDP%J&&=Y<8Kj z@wEHzQj?LCE4aqbjBo4 zZc>{;87qnhN^1t6(3Kha3^5UxmP<6SFOno_cdp@{$FEjyV(C*MatR#>vo#kt({{3?~_jp z^Z%V!|M}-Xw>qul`VU5PvHq_jeUSLiwGH+`AoMk|XixUc!Yc8@!z_C8^yJ0&Coj%R zFHZjO^5pca_vGa4+h-5O5jm(>G6Fxf6K=pZQr0QO($s(L)3(O1b*V`5)J(+T~KP#Ir6OZnPgGWw^lEpc|N zBqLAPbiU%odW9Xb6- L%AU%*073x(GeyLP diff --git a/packages/u-navigator-2026.06.23.r002.tgz b/packages/u-navigator-2026.06.23.r002.tgz new file mode 100644 index 0000000000000000000000000000000000000000..50fcc6b33ca810f62bf47cd8304da6bdb6ab7834 GIT binary patch literal 12528 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 GP5}U5M^9M* literal 0 HcmV?d00001 diff --git a/server/public/app.js b/server/public/app.js index 725cc0d..71bf1c1 100644 --- a/server/public/app.js +++ b/server/public/app.js @@ -8,6 +8,8 @@ const state = { selectedEntry: null, contextMenu: null, draggedEntry: null, + pointerDrag: null, + suppressClickPath: null, jobs: new Map(), nextWindowId: 1, zIndex: 20 @@ -233,41 +235,16 @@ function renderExplorer(body, win) { for (const row of body.querySelectorAll('.file-row')) { const entry = data.entries.find((item) => item.path === row.dataset.path); - row.addEventListener('pointerdown', () => lockExplorerScroll(win, body)); + row.addEventListener('pointerdown', (event) => { + lockExplorerScroll(win, body); + startItemPointerDrag(event, win, entry); + }); row.addEventListener('click', () => selectEntry(win, entry, body)); row.addEventListener('dblclick', () => { if (entry.type === 'directory') { loadExplorer(win, entry.path); } }); - row.addEventListener('dragstart', (event) => { - state.draggedEntry = { path: entry.path, name: entry.name, sourceWindowId: win.id }; - setEffectAllowed(event); - row.classList.add('dragging'); - }); - row.addEventListener('dragend', () => { - row.classList.remove('dragging'); - setTimeout(() => { - state.draggedEntry = null; - }, 0); - }); - row.addEventListener('dragover', (event) => { - if (entry.type === 'directory') { - event.preventDefault(); - event.stopPropagation(); - setDropEffect(event, event.altKey ? 'copy' : 'move'); - } - }); - row.addEventListener('drop', async (event) => { - if (entry.type !== 'directory') return; - event.preventDefault(); - event.stopPropagation(); - try { - await handleDrop(event, win, entry.path); - } catch (error) { - showError(error); - } - }); row.addEventListener('contextmenu', (event) => { event.preventDefault(); event.stopPropagation(); @@ -283,7 +260,7 @@ function renderFileTable(entries) { } const rows = entries.map((entry) => ` - + ${icons[entry.type] || 'Item'}${escapeHtml(entry.name)} ${entry.type} ${entry.type === 'file' ? formatBytes(entry.size) : ''} @@ -528,6 +505,11 @@ async function pollJob(id) { } function selectEntry(win, entry, scrollBody = null) { + if (state.suppressClickPath === entry.path) { + state.suppressClickPath = null; + restoreExplorerScroll(win, scrollBody); + return; + } win.data.selectedPath = entry.path; state.selectedEntry = entry; focusWindow(win); @@ -563,6 +545,121 @@ function updatePropertiesWindows() { } } +function startItemPointerDrag(event, win, entry) { + if (event.button !== 0) return; + + state.pointerDrag = { + sourceWindowId: win.id, + path: entry.path, + name: entry.name, + startX: event.clientX, + startY: event.clientY, + active: false, + targetWindowId: null, + targetPath: null + }; + + const move = (moveEvent) => updateItemPointerDrag(moveEvent); + const up = (upEvent) => finishItemPointerDrag(upEvent, move, up); + document.addEventListener('pointermove', move); + document.addEventListener('pointerup', up, { once: true }); +} + +function updateItemPointerDrag(event) { + const drag = state.pointerDrag; + if (!drag) return; + + const distance = Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY); + if (!drag.active && distance < 6) { + return; + } + + drag.active = true; + event.preventDefault(); + document.body.classList.add('u-nav-dragging'); + markDraggingRow(drag.path, true); + updatePointerDropTarget(event); +} + +async function finishItemPointerDrag(event, move, up) { + document.removeEventListener('pointermove', move); + document.removeEventListener('pointerup', up); + + const drag = state.pointerDrag; + clearPointerDropTarget(); + document.body.classList.remove('u-nav-dragging'); + if (!drag) return; + + markDraggingRow(drag.path, false); + state.pointerDrag = null; + + if (!drag.active) { + return; + } + + state.suppressClickPath = drag.path; + const target = findPointerDropTarget(event); + if (!target) { + return; + } + + try { + const destination = `${target.path.replace(/\/$/, '')}/${drag.name}`; + if (destination === drag.path) { + throw new Error('Quelle und Ziel sind identisch.'); + } + await createJob(event.altKey ? 'copy' : 'move', drag.path, destination); + await reloadExplorerWindows([drag.sourceWindowId, target.windowId]); + } catch (error) { + showError(error); + } +} + +function updatePointerDropTarget(event) { + clearPointerDropTarget(); + const target = findPointerDropTarget(event); + if (!target) return; + + state.pointerDrag.targetWindowId = target.windowId; + state.pointerDrag.targetPath = target.path; + const windowEl = workspace.querySelector(`.window[data-window-id="${target.windowId}"]`); + windowEl?.querySelector('.drop-zone')?.classList.add('drag-over'); + if (target.row) { + target.row.classList.add('drop-target'); + } +} + +function clearPointerDropTarget() { + for (const item of workspace.querySelectorAll('.drop-zone.drag-over')) { + item.classList.remove('drag-over'); + } + for (const item of workspace.querySelectorAll('.file-row.drop-target')) { + item.classList.remove('drop-target'); + } +} + +function findPointerDropTarget(event) { + const element = document.elementFromPoint(event.clientX, event.clientY); + const windowEl = element?.closest?.('.window'); + if (!windowEl) return null; + + const win = state.windows.find((item) => item.id === windowEl.dataset.windowId); + if (!win || win.kind !== 'explorer') return null; + + const row = element.closest?.('.file-row'); + if (row?.dataset.type === 'directory') { + return { windowId: win.id, path: row.dataset.path, row }; + } + + return { windowId: win.id, path: win.data.path, row: null }; +} + +function markDraggingRow(path, dragging) { + for (const row of workspace.querySelectorAll(`.file-row[data-path="${cssEscape(path)}"]`)) { + row.classList.toggle('dragging', dragging); + } +} + function lockExplorerScroll(win, body) { win.data.lockScroll = true; win.data.lockScrollTop = body.scrollTop; @@ -695,6 +792,13 @@ function escapeAttr(value) { return escapeHtml(value); } +function cssEscape(value) { + if (window.CSS?.escape) { + return CSS.escape(String(value)); + } + return String(value).replace(/["\\]/g, '\\$&'); +} + function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } diff --git a/server/public/styles.css b/server/public/styles.css index 6031804..635ed91 100644 --- a/server/public/styles.css +++ b/server/public/styles.css @@ -229,16 +229,30 @@ .u-nav .file-row:hover, .u-nav .file-row.selected, -.u-nav .file-row.dragging { +.u-nav .file-row.dragging, +.u-nav .file-row.drop-target { background: var(--surface-2); } .u-nav .file-row:hover td, .u-nav .file-row.selected td, -.u-nav .file-row.dragging td { +.u-nav .file-row.dragging td, +.u-nav .file-row.drop-target td { background: var(--surface-2) !important; } +.u-nav .file-row { + user-select: none; +} + +.u-nav .file-row.dragging { + opacity: 0.55; +} + +.u-nav-dragging { + cursor: grabbing; +} + .u-nav .name-cell { align-items: center; display: flex; diff --git a/u-navigator.plg b/u-navigator.plg index 2a1ba12..f4d4fb4 100644 --- a/u-navigator.plg +++ b/u-navigator.plg @@ -1,7 +1,7 @@ - + ]> @@ -14,7 +14,7 @@ https://git.casaderoll.de/michael/Unraid-Navigator/raw/branch/main/packages/&package; -54c2deddb4643c26d51b86aca896b52d +0a9e56a6a4ddf7648388b25a3dedb264