Revert to version 990839e

This commit is contained in:
Flatlogic Bot 2026-03-19 11:53:01 +00:00
parent 5d79b82de2
commit 5e2bccdca0

View File

@ -392,18 +392,7 @@ const resolveDurationWithFallback = async (
}
try {
const requestUrl =
playbackUrl.startsWith('http://') || playbackUrl.startsWith('https://')
? playbackUrl
: playbackUrl.replace(/^\/api(?=\/)/, '');
const token =
typeof window !== 'undefined' ? localStorage.getItem('token') || '' : '';
const response = await axios.get(requestUrl, {
responseType: 'blob',
headers: token ? { Authorization: `Bearer ${token}` } : undefined,
});
const response = await axios.get(playbackUrl, { responseType: 'blob' });
const blobUrl = URL.createObjectURL(response.data);
try {
const blobDuration = await readMediaDuration(blobUrl, mediaType);
@ -549,6 +538,7 @@ const createDefaultElement = (
navType: getNavigationButtonKind(type),
iconUrl: '',
transitionReverseMode: 'auto_reverse',
transitionDurationSec: 0.7,
};
}
@ -749,7 +739,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
useState<EditorMenuItem>('none');
const [transitionPreview, setTransitionPreview] =
useState<TransitionPreviewState | null>(null);
const [pendingNavigationPageId, setPendingNavigationPageId] = useState('');
const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
@ -759,6 +748,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
const [newTransitionVideoUrl, setNewTransitionVideoUrl] = useState('');
const [newTransitionSupportsReverse, setNewTransitionSupportsReverse] =
useState(true);
const [newTransitionDurationSec, setNewTransitionDurationSec] = useState(0.7);
const [errorMessage, setErrorMessage] = useState('');
const [successMessage, setSuccessMessage] = useState('');
const [resolvedDurationBySource, setResolvedDurationBySource] = useState<
@ -994,28 +984,8 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
});
}
if (newTransitionVideoUrl) {
targets.push({ source: newTransitionVideoUrl, mediaType: 'video' });
}
elements.forEach((element) => {
if (!isNavigationElementType(element.type)) return;
if (element.transitionVideoUrl) {
targets.push({ source: element.transitionVideoUrl, mediaType: 'video' });
}
if (element.reverseVideoUrl) {
targets.push({ source: element.reverseVideoUrl, mediaType: 'video' });
}
});
return targets;
}, [
backgroundAudioUrl,
backgroundVideoUrl,
elements,
newTransitionVideoUrl,
selectedElement,
]);
}, [backgroundAudioUrl, backgroundVideoUrl, selectedElement]);
useEffect(() => {
let isCancelled = false;
@ -1080,19 +1050,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
getKnownDurationForSource(selectedElement.mediaUrl || ''),
);
}, [getKnownDurationForSource, selectedElement]);
const newTransitionDurationNote = useMemo(
() => formatDurationNote(getKnownDurationForSource(newTransitionVideoUrl)),
[getKnownDurationForSource, newTransitionVideoUrl],
);
const selectedTransitionDurationNote = useMemo(() => {
if (!selectedElement || !isNavigationElementType(selectedElement.type)) {
return 'Duration: unknown';
}
return formatDurationNote(
getKnownDurationForSource(selectedElement.transitionVideoUrl || ''),
);
}, [getKnownDurationForSource, selectedElement]);
useEffect(() => {
if (newTransitionVideoUrl) return;
@ -1100,32 +1057,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
setNewTransitionVideoUrl(transitionVideoAssetOptions[0].value);
}, [newTransitionVideoUrl, transitionVideoAssetOptions]);
useEffect(() => {
setElements((prev) => {
let hasChanges = false;
const next = prev.map((element) => {
if (!isNavigationElementType(element.type)) return element;
const resolvedDuration = getKnownDurationForSource(
element.transitionVideoUrl || '',
);
const nextDuration =
Number.isFinite(resolvedDuration) && Number(resolvedDuration) > 0
? Number(resolvedDuration)
: undefined;
if (element.transitionDurationSec === nextDuration) return element;
hasChanges = true;
return {
...element,
transitionDurationSec: nextDuration,
};
});
return hasChanges ? next : prev;
});
}, [getKnownDurationForSource]);
const loadData = useCallback(async () => {
if (!projectId || !router.isReady || !isAuthReady) return;
@ -1712,13 +1643,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
const sanitizedName =
String(newTransitionName || '').trim() ||
`Transition ${Date.now().toString().slice(-4)}`;
const resolvedDurationSec = getKnownDurationForSource(sanitizedVideoUrl);
if (!resolvedDurationSec) {
setErrorMessage(
'Could not resolve transition video duration yet. Please wait a moment and try again.',
);
return;
}
const parsedDuration = Number(newTransitionDurationSec);
try {
setIsCreatingTransition(true);
@ -1734,7 +1659,10 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
video_url: sanitizedVideoUrl,
audio_url: '',
supports_reverse: Boolean(newTransitionSupportsReverse),
duration_sec: resolvedDurationSec,
duration_sec:
Number.isFinite(parsedDuration) && parsedDuration > 0
? parsedDuration
: 0.7,
};
await axios.post('/transitions', { data: payload });
@ -1752,7 +1680,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
}
}, [
activePage?.environment,
getKnownDurationForSource,
newTransitionDurationSec,
newTransitionName,
newTransitionSupportsReverse,
newTransitionVideoUrl,
@ -1996,44 +1924,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
element.navType === 'back' || element.type === 'navigation_prev'
? 'back'
: 'forward';
const configuredTargetId = String(element.targetPageId || '').trim();
const fallbackTargetId = (() => {
const currentPageIndex = pages.findIndex(
(page) => page.id === activePageId,
);
if (currentPageIndex < 0) return '';
const nextPageIndex =
direction === 'back' ? currentPageIndex - 1 : currentPageIndex + 1;
const nextPage = pages[nextPageIndex];
return nextPage ? String(nextPage.id || '').trim() : '';
})();
const targetPageId = configuredTargetId || fallbackTargetId;
if (!targetPageId) {
setErrorMessage('No target page available for this navigation button.');
return;
}
const hasPlayableTransition =
Boolean(element.transitionVideoUrl) &&
!(
direction === 'back' &&
element.transitionReverseMode === 'separate_video' &&
!element.reverseVideoUrl
);
if (!hasPlayableTransition) {
setPendingNavigationPageId('');
setTransitionPreview(null);
setActivePageId(targetPageId);
setSelectedElementId('');
setSelectedMenuItem('none');
setErrorMessage('');
return;
}
setPendingNavigationPageId(targetPageId);
openTransitionPreviewForElement(element, direction);
}
return;
@ -2376,16 +2266,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
const finishPreview = () => {
cleanupReverseFrame();
setTransitionPreview(null);
setPendingNavigationPageId((pendingPageId) => {
const nextPageId = String(pendingPageId || '').trim();
if (nextPageId) {
setActivePageId(nextPageId);
setSelectedElementId('');
setSelectedMenuItem('none');
setErrorMessage('');
}
return '';
});
};
const configuredDurationMs =
@ -2820,10 +2700,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
</option>
))}
</select>
<p className='text-[11px] text-gray-500'>
Transition duration is automatic from video metadata.{' '}
{newTransitionDurationNote}
</p>
<label className='flex items-center gap-2 text-[11px] text-gray-700'>
<input
type='checkbox'
@ -2834,6 +2710,18 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
/>
Supports reverse playback
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
type='number'
min='0.2'
step='0.1'
value={newTransitionDurationSec}
onChange={(event) =>
setNewTransitionDurationSec(
Number(event.target.value || 0.7),
)
}
/>
<button
type='button'
className='menu-action-btn'
@ -3000,9 +2888,6 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
</option>
))}
</select>
<p className='mt-1 text-[11px] text-gray-500'>
{selectedMediaDurationNote}
</p>
</div>
<div>
<label className='mb-1 block text-[11px] font-semibold text-gray-600'>
@ -3034,15 +2919,11 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
<select
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={selectedElement.transitionVideoUrl || ''}
onChange={(event) => {
const nextVideoUrl = event.target.value;
const resolvedDuration =
getKnownDurationForSource(nextVideoUrl);
onChange={(event) =>
updateSelectedElement({
transitionVideoUrl: nextVideoUrl,
transitionDurationSec: resolvedDuration || undefined,
});
}}
transitionVideoUrl: event.target.value,
})
}
>
<option value=''>Not selected</option>
{addFallbackAssetOption(
@ -3056,7 +2937,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
))}
</select>
<p className='mt-1 text-[11px] text-gray-500'>
{selectedTransitionDurationNote}
{selectedMediaDurationNote}
</p>
</div>
<div>
@ -3114,10 +2995,25 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
</select>
</div>
)}
<p className='text-[11px] text-gray-500'>
Transition duration is set automatically from the selected
video. {selectedTransitionDurationNote}
</p>
<div>
<label className='mb-1 block text-[11px] font-semibold text-gray-600'>
Transition duration (sec)
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
type='number'
min='0.2'
step='0.1'
value={selectedElement.transitionDurationSec ?? 0.7}
onChange={(event) =>
updateSelectedElement({
transitionDurationSec: Number(
event.target.value || 0.7,
),
})
}
/>
</div>
<div className='flex gap-2 pt-1'>
<BaseButton
small
@ -3688,19 +3584,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
<button
type='button'
className='absolute top-4 right-4 rounded bg-white/20 px-3 py-1 text-xs text-white hover:bg-white/30'
onClick={() => {
setTransitionPreview(null);
setPendingNavigationPageId((pendingPageId) => {
const nextPageId = String(pendingPageId || '').trim();
if (nextPageId) {
setActivePageId(nextPageId);
setSelectedElementId('');
setSelectedMenuItem('none');
setErrorMessage('');
}
return '';
});
}}
onClick={() => setTransitionPreview(null)}
>
Close
</button>