Upload folder using huggingface_hub
Browse files
client/src/pages/TutorialTasks.tsx
CHANGED
|
@@ -77,6 +77,7 @@ const TutorialTasks: React.FC = () => {
|
|
| 77 |
const submissionsGridRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
|
| 78 |
const submissionsContainerRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
|
| 79 |
const withPreservedScroll = useRef<(fn: () => void) => void>();
|
|
|
|
| 80 |
|
| 81 |
const setGlobalAnchorDisabled = (disabled: boolean) => {
|
| 82 |
try {
|
|
@@ -911,13 +912,29 @@ const TutorialTasks: React.FC = () => {
|
|
| 911 |
setTranslationText({ ...translationText, [taskId]: '' });
|
| 912 |
setSelectedGroups({ ...selectedGroups, [taskId]: 0 });
|
| 913 |
// Narrow refetch: only this task's submissions
|
|
|
|
| 914 |
api.get(`/api/submissions/by-source/${taskId}`).then(r => {
|
| 915 |
const list = (r.data && r.data.submissions) || [];
|
| 916 |
setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
|
| 917 |
// Release spacer one frame after list update to avoid jump
|
| 918 |
-
requestAnimationFrame(() =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 919 |
}).catch(() => {
|
| 920 |
-
requestAnimationFrame(() =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 921 |
});
|
| 922 |
});
|
| 923 |
});
|
|
@@ -933,6 +950,8 @@ const TutorialTasks: React.FC = () => {
|
|
| 933 |
});
|
| 934 |
// release after a couple frames to let DOM settle (extra frame on Safari)
|
| 935 |
const release = () => {
|
|
|
|
|
|
|
| 936 |
unlockListHeight();
|
| 937 |
unlockCardHeightById(taskId);
|
| 938 |
unlockGridHeightById(taskId);
|
|
|
|
| 77 |
const submissionsGridRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
|
| 78 |
const submissionsContainerRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
|
| 79 |
const withPreservedScroll = useRef<(fn: () => void) => void>();
|
| 80 |
+
const pendingUnlocksRef = useRef<Set<string>>(new Set());
|
| 81 |
|
| 82 |
const setGlobalAnchorDisabled = (disabled: boolean) => {
|
| 83 |
try {
|
|
|
|
| 912 |
setTranslationText({ ...translationText, [taskId]: '' });
|
| 913 |
setSelectedGroups({ ...selectedGroups, [taskId]: 0 });
|
| 914 |
// Narrow refetch: only this task's submissions
|
| 915 |
+
pendingUnlocksRef.current.add(taskId);
|
| 916 |
api.get(`/api/submissions/by-source/${taskId}`).then(r => {
|
| 917 |
const list = (r.data && r.data.submissions) || [];
|
| 918 |
setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
|
| 919 |
// Release spacer one frame after list update to avoid jump
|
| 920 |
+
requestAnimationFrame(() => {
|
| 921 |
+
setSpacerHeights(prev => ({ ...prev, [taskId]: 0 }));
|
| 922 |
+
// Now that the grid has the final height, safely unlock
|
| 923 |
+
unlockListHeight();
|
| 924 |
+
unlockCardHeightById(taskId);
|
| 925 |
+
unlockGridHeightById(taskId);
|
| 926 |
+
pendingUnlocksRef.current.delete(taskId);
|
| 927 |
+
if (isSafari) { unfreezeScroll(); }
|
| 928 |
+
});
|
| 929 |
}).catch(() => {
|
| 930 |
+
requestAnimationFrame(() => {
|
| 931 |
+
setSpacerHeights(prev => ({ ...prev, [taskId]: 0 }));
|
| 932 |
+
unlockListHeight();
|
| 933 |
+
unlockCardHeightById(taskId);
|
| 934 |
+
unlockGridHeightById(taskId);
|
| 935 |
+
pendingUnlocksRef.current.delete(taskId);
|
| 936 |
+
if (isSafari) { unfreezeScroll(); }
|
| 937 |
+
});
|
| 938 |
});
|
| 939 |
});
|
| 940 |
});
|
|
|
|
| 950 |
});
|
| 951 |
// release after a couple frames to let DOM settle (extra frame on Safari)
|
| 952 |
const release = () => {
|
| 953 |
+
// If a gated refetch is in-flight, defer unlock until postRefetch block
|
| 954 |
+
if (pendingUnlocksRef.current.has(taskId)) return;
|
| 955 |
unlockListHeight();
|
| 956 |
unlockCardHeightById(taskId);
|
| 957 |
unlockGridHeightById(taskId);
|