Upload folder using huggingface_hub
Browse files
client/src/pages/TutorialTasks.tsx
CHANGED
|
@@ -857,11 +857,24 @@ const TutorialTasks: React.FC = () => {
|
|
| 857 |
return { ...prev, [taskId]: next };
|
| 858 |
});
|
| 859 |
|
| 860 |
-
// Defer
|
|
|
|
|
|
|
|
|
|
|
|
|
| 861 |
withPreservedCardOffset(taskId, () => {
|
| 862 |
React.startTransition(() => {
|
| 863 |
setTranslationText({ ...translationText, [taskId]: '' });
|
| 864 |
setSelectedGroups({ ...selectedGroups, [taskId]: 0 });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 865 |
});
|
| 866 |
});
|
| 867 |
} else {
|
|
@@ -874,12 +887,12 @@ const TutorialTasks: React.FC = () => {
|
|
| 874 |
withPreservedCardOffset(taskId, () => {
|
| 875 |
setSubmitting({ ...submitting, [taskId]: false });
|
| 876 |
});
|
| 877 |
-
// release after a
|
| 878 |
-
requestAnimationFrame(() => requestAnimationFrame(() => {
|
| 879 |
unlockListHeight();
|
| 880 |
unlockCardHeightById(taskId);
|
| 881 |
unlockGridHeightById(taskId);
|
| 882 |
-
}));
|
| 883 |
setMutatingTaskId(null);
|
| 884 |
}
|
| 885 |
};
|
|
@@ -941,10 +954,27 @@ const TutorialTasks: React.FC = () => {
|
|
| 941 |
});
|
| 942 |
}
|
| 943 |
|
| 944 |
-
//
|
| 945 |
if (taskId) lockCardHeightById(taskId);
|
| 946 |
withPreservedCardOffset(taskId || '', () => {
|
| 947 |
-
React.startTransition(() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 948 |
});
|
| 949 |
} else {
|
| 950 |
|
|
@@ -2253,7 +2283,7 @@ const TutorialTasks: React.FC = () => {
|
|
| 2253 |
expandedSections[task._id]
|
| 2254 |
? 'max-h-none overflow-visible'
|
| 2255 |
: 'max-h-0 overflow-hidden'
|
| 2256 |
-
}`}>
|
| 2257 |
{userSubmissions[task._id].map((submission, index) => (
|
| 2258 |
<div key={submission._id} className="bg-white rounded-lg p-3 border border-stone-200 flex flex-col justify-between h-full">
|
| 2259 |
<div className="flex items-center justify-between mb-2">
|
|
|
|
| 857 |
return { ...prev, [taskId]: next };
|
| 858 |
});
|
| 859 |
|
| 860 |
+
// Defer state updates and minimal refetch
|
| 861 |
+
// Measure grid height and set spacer before refetch to keep layout height constant
|
| 862 |
+
const gridEl = submissionsGridRefs.current[taskId];
|
| 863 |
+
const gridHeight = gridEl ? gridEl.getBoundingClientRect().height : 0;
|
| 864 |
+
if (gridHeight > 0) setSpacerHeights(prev => ({ ...prev, [taskId]: gridHeight }));
|
| 865 |
withPreservedCardOffset(taskId, () => {
|
| 866 |
React.startTransition(() => {
|
| 867 |
setTranslationText({ ...translationText, [taskId]: '' });
|
| 868 |
setSelectedGroups({ ...selectedGroups, [taskId]: 0 });
|
| 869 |
+
// Narrow refetch: only this task's submissions
|
| 870 |
+
api.get(`/api/submissions/by-source/${taskId}`).then(r => {
|
| 871 |
+
const list = (r.data && r.data.submissions) || [];
|
| 872 |
+
setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
|
| 873 |
+
// Release spacer one frame after list update to avoid jump
|
| 874 |
+
requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
|
| 875 |
+
}).catch(() => {
|
| 876 |
+
requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
|
| 877 |
+
});
|
| 878 |
});
|
| 879 |
});
|
| 880 |
} else {
|
|
|
|
| 887 |
withPreservedCardOffset(taskId, () => {
|
| 888 |
setSubmitting({ ...submitting, [taskId]: false });
|
| 889 |
});
|
| 890 |
+
// release after a few frames to let Safari settle layout
|
| 891 |
+
requestAnimationFrame(() => requestAnimationFrame(() => requestAnimationFrame(() => {
|
| 892 |
unlockListHeight();
|
| 893 |
unlockCardHeightById(taskId);
|
| 894 |
unlockGridHeightById(taskId);
|
| 895 |
+
})));
|
| 896 |
setMutatingTaskId(null);
|
| 897 |
}
|
| 898 |
};
|
|
|
|
| 954 |
});
|
| 955 |
}
|
| 956 |
|
| 957 |
+
// Defer refetch to prevent UI jumping and preserve scroll around DOM updates
|
| 958 |
if (taskId) lockCardHeightById(taskId);
|
| 959 |
withPreservedCardOffset(taskId || '', () => {
|
| 960 |
+
React.startTransition(() => {
|
| 961 |
+
// Narrow refetch: only this task's submissions
|
| 962 |
+
if (taskId) {
|
| 963 |
+
const gridEl = submissionsGridRefs.current[taskId];
|
| 964 |
+
const gridHeight = gridEl ? gridEl.getBoundingClientRect().height : 0;
|
| 965 |
+
if (gridHeight > 0) setSpacerHeights(prev => ({ ...prev, [taskId]: gridHeight }));
|
| 966 |
+
api.get(`/api/submissions/by-source/${taskId}`).then(r => {
|
| 967 |
+
const list = (r.data && r.data.submissions) || [];
|
| 968 |
+
setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
|
| 969 |
+
requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
|
| 970 |
+
}).catch(() => {
|
| 971 |
+
requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
|
| 972 |
+
});
|
| 973 |
+
} else {
|
| 974 |
+
// Fallback
|
| 975 |
+
requestAnimationFrame(() => requestAnimationFrame(() => fetchUserSubmissions(tutorialTasks)));
|
| 976 |
+
}
|
| 977 |
+
});
|
| 978 |
});
|
| 979 |
} else {
|
| 980 |
|
|
|
|
| 2283 |
expandedSections[task._id]
|
| 2284 |
? 'max-h-none overflow-visible'
|
| 2285 |
: 'max-h-0 overflow-hidden'
|
| 2286 |
+
}`} style={{ contain: 'layout paint size' }}>
|
| 2287 |
{userSubmissions[task._id].map((submission, index) => (
|
| 2288 |
<div key={submission._id} className="bg-white rounded-lg p-3 border border-stone-200 flex flex-col justify-between h-full">
|
| 2289 |
<div className="flex items-center justify-between mb-2">
|