linguabot commited on
Commit
381f4d2
·
verified ·
1 Parent(s): 0154734

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. client/src/components/Refinity.tsx +120 -5
client/src/components/Refinity.tsx CHANGED
@@ -223,9 +223,55 @@ const Refinity: React.FC = () => {
223
  if (idx >= 0) return idx;
224
  return Math.min(Math.max(taskVersions.length - 1, 0), flowIndex);
225
  }, [taskVersions, currentVersionId, flowIndex]);
 
226
 
227
  // Keyboard navigation disabled per request (use arrow buttons only)
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  const uploadDocx = async (file: File) => {
230
  setUploading(true);
231
  try {
@@ -822,7 +868,27 @@ const Refinity: React.FC = () => {
822
  <div className="pointer-events-none absolute text-gray-700" style={{ left: '1.5rem', bottom: '6rem', zIndex: 2000 }}>…</div>
823
  )}
824
  {isCenter && (
825
- <div className="action-row absolute left-6 right-6 bottom-6 swiper-no-swiping" data-version-number={v.versionNumber} style={{ pointerEvents: 'auto', transform: 'translateZ(0)', zIndex: 3000 }}>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
826
  {/* Invisible first child to bypass first-child quirks while matching pill styles (kept in place) */}
827
  <button
828
  type="button"
@@ -834,12 +900,35 @@ const Refinity: React.FC = () => {
834
  <div className="flex justify-center gap-3 w-full">
835
  <button
836
  type="button"
 
 
 
 
 
837
  onClick={(e) => {
838
  e.preventDefault();
839
  e.stopPropagation();
840
- console.log('Revise clicked for version:', v.versionNumber, 'id:', v.id);
841
  selectManual(v.id);
842
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 bg-violet-600/70 hover:bg-violet-700 active:translate-y-0.5 transition-all duration-200"
844
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
845
  >
@@ -850,7 +939,8 @@ const Refinity: React.FC = () => {
850
  {(String(v.revisedBy || v.originalAuthor || '').toLowerCase() === String(username).toLowerCase() || isAdmin) && (
851
  <button
852
  type="button"
853
- onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); setCurrentVersionId(v.id); setEditingVersionId(v.id); setStage('editor'); }}
 
854
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-gray-800 ring-1 ring-inset ring-gray-300 bg-white/20 backdrop-blur-md hover:bg-gray-100 active:translate-y-0.5 transition-all duration-200"
855
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
856
  >
@@ -859,6 +949,7 @@ const Refinity: React.FC = () => {
859
  )}
860
  <button
861
  type="button"
 
862
  onClick={(e)=>{
863
  e.preventDefault(); e.stopPropagation();
864
  // Export single version content as simple .docx (inline changes off)
@@ -883,7 +974,8 @@ const Refinity: React.FC = () => {
883
  </button>
884
  <button
885
  type="button"
886
- onClick={(e) => { e.preventDefault(); e.stopPropagation(); setCompareUIOpen(true); if (!compareA) setCompareA(v.id); }}
 
887
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-gray-800 ring-1 ring-inset ring-gray-300 bg-white/20 backdrop-blur-md hover:bg-gray-100 active:translate-y-0.5 transition-all duration-200"
888
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
889
  >
@@ -892,7 +984,8 @@ const Refinity: React.FC = () => {
892
  {(isAdmin || String(v.revisedBy || v.originalAuthor || '').toLowerCase() === String(username).toLowerCase()) && (
893
  <button
894
  type="button"
895
- onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); deleteVersion(v.id); }}
 
896
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-red-700 ring-1 ring-inset ring-red-300 bg-white/20 backdrop-blur-md hover:bg-red-600 hover:text-white active:translate-y-0.5 transition-all duration-200"
897
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
898
  >
@@ -907,6 +1000,28 @@ const Refinity: React.FC = () => {
907
  );
908
  })}
909
  </SwiperRoot>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
910
 
911
  {/* External V2 Revise Button removed per user request */}
912
 
 
223
  if (idx >= 0) return idx;
224
  return Math.min(Math.max(taskVersions.length - 1, 0), flowIndex);
225
  }, [taskVersions, currentVersionId, flowIndex]);
226
+ const centerVersionId = React.useMemo(() => (taskVersions[flowIndex]?.id) || '', [taskVersions, flowIndex]);
227
 
228
  // Keyboard navigation disabled per request (use arrow buttons only)
229
 
230
+ // Non-visual overlay to guarantee Revise clickability on all platforms without changing layout
231
+ const reviseBtnRefs = React.useRef<Record<string, HTMLButtonElement | null>>({});
232
+ const [reviseOverlay, setReviseOverlay] = React.useState<{ left: number; top: number; width: number; height: number; vid: string } | null>(null);
233
+ const updateReviseOverlay = React.useCallback(() => {
234
+ try {
235
+ const v = taskVersions[flowIndex];
236
+ if (!v) { setReviseOverlay(null); return; }
237
+ const el = reviseBtnRefs.current[v.id || ''];
238
+ if (!el) { setReviseOverlay(null); return; }
239
+ const r = el.getBoundingClientRect();
240
+ if (r.width === 0 || r.height === 0) { setReviseOverlay(null); return; }
241
+ setReviseOverlay({ left: Math.max(0, r.left), top: Math.max(0, r.top), width: r.width, height: r.height, vid: v.id });
242
+ } catch { setReviseOverlay(null); }
243
+ }, [taskVersions, flowIndex]);
244
+ React.useLayoutEffect(() => { updateReviseOverlay(); }, [updateReviseOverlay, isFullscreen, compareUIOpen, revDownloadOpen]);
245
+ React.useEffect(() => {
246
+ // After slide changes, measure across a few frames and after a short delay
247
+ let raf1 = 0, raf2 = 0, raf3 = 0;
248
+ const tick = () => updateReviseOverlay();
249
+ raf1 = window.requestAnimationFrame(() => {
250
+ tick();
251
+ raf2 = window.requestAnimationFrame(() => {
252
+ tick();
253
+ raf3 = window.requestAnimationFrame(() => tick());
254
+ });
255
+ });
256
+ const t = window.setTimeout(tick, 260);
257
+ return () => {
258
+ window.cancelAnimationFrame(raf1);
259
+ window.cancelAnimationFrame(raf2);
260
+ window.cancelAnimationFrame(raf3);
261
+ window.clearTimeout(t);
262
+ };
263
+ }, [flowIndex, centerVersionId, updateReviseOverlay]);
264
+ React.useEffect(() => {
265
+ const onResize = () => updateReviseOverlay();
266
+ const onScroll = () => updateReviseOverlay();
267
+ window.addEventListener('resize', onResize, { passive: true } as any);
268
+ window.addEventListener('scroll', onScroll, { passive: true } as any);
269
+ return () => {
270
+ window.removeEventListener('resize', onResize as any);
271
+ window.removeEventListener('scroll', onScroll as any);
272
+ };
273
+ }, [updateReviseOverlay]);
274
+
275
  const uploadDocx = async (file: File) => {
276
  setUploading(true);
277
  try {
 
868
  <div className="pointer-events-none absolute text-gray-700" style={{ left: '1.5rem', bottom: '6rem', zIndex: 2000 }}>…</div>
869
  )}
870
  {isCenter && (
871
+ <div
872
+ className="action-row absolute left-6 right-6 bottom-6 swiper-no-swiping"
873
+ data-version-number={v.versionNumber}
874
+ data-version-index={idx}
875
+ data-version-id={v.id}
876
+ data-owner={String(v.revisedBy || v.originalAuthor || '').toLowerCase() === String(username).toLowerCase() || !!isAdmin}
877
+ onClickCapture={(e)=> {
878
+ // Diagnostic: capture clicks within action row to ensure they are not swallowed by slide
879
+ const t = e.target as HTMLElement;
880
+ console.debug('[VF] action-row click(capture)', {
881
+ idx,
882
+ versionId: v.id,
883
+ buttonData: t?.dataset || {},
884
+ targetTag: t?.tagName,
885
+ targetClasses: t?.className
886
+ });
887
+ }}
888
+ onMouseEnter={()=>{ updateReviseOverlay(); }}
889
+ onMouseMove={()=>{ updateReviseOverlay(); }}
890
+ style={{ pointerEvents: 'auto', transform: 'translateZ(0)', zIndex: 3000 }}
891
+ >
892
  {/* Invisible first child to bypass first-child quirks while matching pill styles (kept in place) */}
893
  <button
894
  type="button"
 
900
  <div className="flex justify-center gap-3 w-full">
901
  <button
902
  type="button"
903
+ data-btn="revise"
904
+ ref={(el)=>{ reviseBtnRefs.current[v.id] = el; }}
905
+ onClickCapture={(e)=>{ e.stopPropagation(); }}
906
+ onPointerDown={(e)=>{ e.stopPropagation(); }}
907
+ onPointerUp={(e)=>{ e.stopPropagation(); }}
908
  onClick={(e) => {
909
  e.preventDefault();
910
  e.stopPropagation();
911
+ console.debug('[VF] Revise click', { idx, versionId: v.id, versionNumber: v.versionNumber });
912
  selectManual(v.id);
913
  }}
914
+ onMouseEnter={(e) => {
915
+ // Diagnostic: inspect computed styles which could affect clickability
916
+ try {
917
+ const el = e.currentTarget as HTMLElement;
918
+ const elCS = window.getComputedStyle(el);
919
+ const parent = el.parentElement;
920
+ const parentCS = parent ? window.getComputedStyle(parent) : null;
921
+ const row = el.closest('.action-row') as HTMLElement | null;
922
+ const rowCS = row ? window.getComputedStyle(row) : null;
923
+ console.debug('[VF] Revise hover styles', {
924
+ idx,
925
+ versionId: v.id,
926
+ el: { zIndex: elCS.zIndex, pointerEvents: elCS.pointerEvents, position: elCS.position },
927
+ parent: parentCS ? { zIndex: parentCS.zIndex, pointerEvents: parentCS.pointerEvents, position: parentCS.position } : null,
928
+ row: rowCS ? { zIndex: rowCS.zIndex, pointerEvents: rowCS.pointerEvents, position: rowCS.position } : null
929
+ });
930
+ } catch {}
931
+ }}
932
  className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 bg-violet-600/70 hover:bg-violet-700 active:translate-y-0.5 transition-all duration-200"
933
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
934
  >
 
939
  {(String(v.revisedBy || v.originalAuthor || '').toLowerCase() === String(username).toLowerCase() || isAdmin) && (
940
  <button
941
  type="button"
942
+ data-btn="edit"
943
+ onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); console.debug('[VF] Edit click', { idx, versionId: v.id }); setCurrentVersionId(v.id); setEditingVersionId(v.id); setStage('editor'); }}
944
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-gray-800 ring-1 ring-inset ring-gray-300 bg-white/20 backdrop-blur-md hover:bg-gray-100 active:translate-y-0.5 transition-all duration-200"
945
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
946
  >
 
949
  )}
950
  <button
951
  type="button"
952
+ data-btn="download"
953
  onClick={(e)=>{
954
  e.preventDefault(); e.stopPropagation();
955
  // Export single version content as simple .docx (inline changes off)
 
974
  </button>
975
  <button
976
  type="button"
977
+ data-btn="compare"
978
+ onClick={(e) => { e.preventDefault(); e.stopPropagation(); console.debug('[VF] Compare click', { idx, versionId: v.id }); setCompareUIOpen(true); if (!compareA) setCompareA(v.id); }}
979
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-gray-800 ring-1 ring-inset ring-gray-300 bg-white/20 backdrop-blur-md hover:bg-gray-100 active:translate-y-0.5 transition-all duration-200"
980
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
981
  >
 
984
  {(isAdmin || String(v.revisedBy || v.originalAuthor || '').toLowerCase() === String(username).toLowerCase()) && (
985
  <button
986
  type="button"
987
+ data-btn="delete"
988
+ onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); console.debug('[VF] Delete click', { idx, versionId: v.id }); deleteVersion(v.id); }}
989
  className="relative inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-2xl text-red-700 ring-1 ring-inset ring-red-300 bg-white/20 backdrop-blur-md hover:bg-red-600 hover:text-white active:translate-y-0.5 transition-all duration-200"
990
  style={{ position: 'relative', zIndex: 3100, pointerEvents: 'auto', cursor: 'pointer', touchAction: 'manipulation' }}
991
  >
 
1000
  );
1001
  })}
1002
  </SwiperRoot>
1003
+ {reviseOverlay && createPortal(
1004
+ <button
1005
+ aria-label="Revise overlay"
1006
+ style={{
1007
+ position: 'fixed',
1008
+ left: `${reviseOverlay.left}px`,
1009
+ top: `${reviseOverlay.top}px`,
1010
+ width: `${reviseOverlay.width}px`,
1011
+ height: `${reviseOverlay.height}px`,
1012
+ background: 'transparent',
1013
+ border: 'none',
1014
+ padding: 0,
1015
+ margin: 0,
1016
+ cursor: 'pointer',
1017
+ zIndex: 2147483000
1018
+ }}
1019
+ onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); selectManual(reviseOverlay.vid); }}
1020
+ onPointerDown={(e)=>{ e.stopPropagation(); }}
1021
+ onPointerUp={(e)=>{ e.stopPropagation(); }}
1022
+ />,
1023
+ document.body
1024
+ )}
1025
 
1026
  {/* External V2 Revise Button removed per user request */}
1027