Upload folder using huggingface_hub
Browse files
client/src/components/Refinity.tsx
CHANGED
|
@@ -183,6 +183,29 @@ const Refinity: React.FC = () => {
|
|
| 183 |
}
|
| 184 |
};
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
const uploadSourceDoc = async (file: File) => {
|
| 187 |
setAddingSourceUploading(true);
|
| 188 |
try {
|
|
@@ -503,8 +526,6 @@ const Refinity: React.FC = () => {
|
|
| 503 |
style={{ height: isFullscreen ? 'calc(100vh - 96px)' : 'min(76vh, calc(100vh - 220px))', minHeight: '340px' }}
|
| 504 |
>
|
| 505 |
{taskVersions.map((v, idx) => {
|
| 506 |
-
const limit = 160;
|
| 507 |
-
const snippet = (v.content || '').slice(0, limit) + ((v.content || '').length > limit ? '…' : '');
|
| 508 |
const isCenter = idx === flowIndex;
|
| 509 |
return (
|
| 510 |
<SwiperSlide key={v.id} style={{ width: 'clamp(320px, 48vw, 720px)', height: isFullscreen ? '72vh' : '62.4vh', zIndex: (idx === flowIndex ? 1000 : (Math.abs(idx - flowIndex) === 1 ? 500 : 1)) }}>
|
|
@@ -517,7 +538,16 @@ const Refinity: React.FC = () => {
|
|
| 517 |
<div className={`ref-card-overlay pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-30`} />
|
| 518 |
<div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
|
| 519 |
<div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
|
| 520 |
-
<div
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 521 |
{isCenter && (
|
| 522 |
<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 }}>
|
| 523 |
{/* Invisible first child to bypass first-child quirks while matching pill styles (kept in place) */}
|
|
|
|
| 183 |
}
|
| 184 |
};
|
| 185 |
|
| 186 |
+
// Flow slide text overflow measurement for multi-line ellipsis indicator
|
| 187 |
+
const textRefs = React.useRef<{ [id: string]: HTMLDivElement | null }>({});
|
| 188 |
+
const [overflowMap, setOverflowMap] = React.useState<{ [id: string]: boolean }>({});
|
| 189 |
+
const recomputeOverflow = React.useCallback(() => {
|
| 190 |
+
const next: { [id: string]: boolean } = {};
|
| 191 |
+
try {
|
| 192 |
+
(versions || []).forEach((v) => {
|
| 193 |
+
const el = textRefs.current[v.id];
|
| 194 |
+
if (el) next[v.id] = el.scrollHeight > el.clientHeight + 1;
|
| 195 |
+
});
|
| 196 |
+
} catch {}
|
| 197 |
+
setOverflowMap(next);
|
| 198 |
+
}, [versions]);
|
| 199 |
+
React.useEffect(() => {
|
| 200 |
+
recomputeOverflow();
|
| 201 |
+
}, [recomputeOverflow, flowIndex, isFullscreen]);
|
| 202 |
+
React.useEffect(() => {
|
| 203 |
+
const onResize = () => recomputeOverflow();
|
| 204 |
+
window.addEventListener('resize', onResize);
|
| 205 |
+
const id = window.setInterval(onResize, 600);
|
| 206 |
+
return () => { window.removeEventListener('resize', onResize); window.clearInterval(id); };
|
| 207 |
+
}, [recomputeOverflow]);
|
| 208 |
+
|
| 209 |
const uploadSourceDoc = async (file: File) => {
|
| 210 |
setAddingSourceUploading(true);
|
| 211 |
try {
|
|
|
|
| 526 |
style={{ height: isFullscreen ? 'calc(100vh - 96px)' : 'min(76vh, calc(100vh - 220px))', minHeight: '340px' }}
|
| 527 |
>
|
| 528 |
{taskVersions.map((v, idx) => {
|
|
|
|
|
|
|
| 529 |
const isCenter = idx === flowIndex;
|
| 530 |
return (
|
| 531 |
<SwiperSlide key={v.id} style={{ width: 'clamp(320px, 48vw, 720px)', height: isFullscreen ? '72vh' : '62.4vh', zIndex: (idx === flowIndex ? 1000 : (Math.abs(idx - flowIndex) === 1 ? 500 : 1)) }}>
|
|
|
|
| 538 |
<div className={`ref-card-overlay pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-30`} />
|
| 539 |
<div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
|
| 540 |
<div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
|
| 541 |
+
<div
|
| 542 |
+
ref={(el)=>{ textRefs.current[v.id]=el; }}
|
| 543 |
+
className={`text-gray-900 whitespace-pre-wrap break-words leading-relaxed flex-1 overflow-hidden pr-1 relative`}
|
| 544 |
+
style={{ paddingBottom: '6.5rem' }}
|
| 545 |
+
>
|
| 546 |
+
{v.content || ''}
|
| 547 |
+
{overflowMap[v.id] && (
|
| 548 |
+
<span className="pointer-events-none absolute right-2" style={{ bottom: '5rem' }}>…</span>
|
| 549 |
+
)}
|
| 550 |
+
</div>
|
| 551 |
{isCenter && (
|
| 552 |
<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 }}>
|
| 553 |
{/* Invisible first child to bypass first-child quirks while matching pill styles (kept in place) */}
|