"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineClipboardKeybindings = exports.getPasteEffectPropTarget = exports.getEasingClipboardDataFromSelection = exports.getEffectPropClipboardDataFromSelection = exports.getEffectsClipboardEnvelopeFromSelections = exports.getEffectClipboardDataFromSelections = exports.getSnapshotsFromSelection = exports.getPasteEffectsTarget = void 0;
const studio_shared_1 = require("@remotion/studio-shared");
const react_1 = require("react");
const remotion_1 = require("remotion");
const client_id_1 = require("../../helpers/client-id");
const use_keybinding_1 = require("../../helpers/use-keybinding");
const call_api_1 = require("../call-api");
const ConfirmationDialog_1 = require("../ConfirmationDialog");
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
const effects_clipboard_1 = require("./effects-clipboard");
const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
const save_effect_prop_1 = require("./save-effect-prop");
const TimelineSelection_1 = require("./TimelineSelection");
const update_selected_easing_1 = require("./update-selected-easing");
const makeClipboardText = (payload) => JSON.stringify(payload);
const makeTargetKey = (nodePath) => {
    return JSON.stringify({
        absolutePath: nodePath.absolutePath,
        nodePath: nodePath.nodePath,
        sequenceKeys: nodePath.sequenceKeys,
    });
};
const isVisibleFieldSchema = (fieldSchema) => fieldSchema !== undefined && fieldSchema.type !== 'hidden';
const getDefaultValue = (fieldSchema) => fieldSchema.default !== undefined
    ? JSON.stringify(fieldSchema.default)
    : null;
const getTargetSequenceNodePathInfo = (selection) => {
    if (selection.type === 'sequence' ||
        selection.type === 'sequence-effect' ||
        selection.type === 'sequence-all-effects') {
        return selection.nodePathInfo;
    }
    return null;
};
const getCopyType = (selection) => {
    if (selection.type === 'sequence-effect') {
        return 'effects-additive';
    }
    if (selection.type === 'sequence-all-effects') {
        return 'effects-replacing';
    }
    return null;
};
const getPasteEffectsTarget = (selectedItems) => {
    const targetNodePathInfos = selectedItems
        .map(getTargetSequenceNodePathInfo)
        .filter((targetNodePathInfo) => targetNodePathInfo !== null);
    const uniqueTargetKeys = new Set(targetNodePathInfos.map((targetNodePathInfo) => makeTargetKey(targetNodePathInfo.sequenceSubscriptionKey)));
    if (uniqueTargetKeys.size === 0) {
        return { type: 'none' };
    }
    if (uniqueTargetKeys.size !== 1) {
        return { type: 'multiple' };
    }
    const [nodePathInfo] = targetNodePathInfos;
    if (!nodePathInfo) {
        return { type: 'none' };
    }
    if (!nodePathInfo.supportsEffects) {
        return { type: 'unsupported' };
    }
    return {
        type: 'valid',
        nodePathInfo,
    };
};
exports.getPasteEffectsTarget = getPasteEffectsTarget;
const isClipboardInterpolationFunction = (value) => {
    return (0, studio_shared_1.isKeyframeInterpolationFunction)(value);
};
const effectPropStatusToClipboardParam = (prop) => {
    if (prop.status === 'computed') {
        return null;
    }
    if (prop.status === 'static') {
        if (prop.codeValue === undefined) {
            return null;
        }
        return {
            type: 'static',
            value: prop.codeValue,
        };
    }
    if (!isClipboardInterpolationFunction(prop.interpolationFunction)) {
        return null;
    }
    return {
        type: 'keyframed',
        interpolationFunction: prop.interpolationFunction,
        keyframes: prop.keyframes,
        easing: prop.easing,
        clamping: prop.clamping,
        ...(prop.output === undefined || prop.output === 'linear'
            ? {}
            : { output: prop.output }),
        ...(prop.posterize === undefined ? {} : { posterize: prop.posterize }),
    };
};
const effectStatusToSnapshot = (effect) => {
    if (effect.importPath === null) {
        return null;
    }
    const params = {};
    for (const [key, prop] of Object.entries(effect.props)) {
        if (prop.status === 'static' && prop.codeValue === undefined) {
            continue;
        }
        const param = effectPropStatusToClipboardParam(prop);
        if (param === null) {
            return null;
        }
        params[key] = param;
    }
    return {
        callee: effect.callee,
        importPath: effect.importPath,
        params,
    };
};
const getSnapshotsFromSelection = ({ selection, propStatuses, }) => {
    if (selection.type !== 'sequence-effect' &&
        selection.type !== 'sequence-all-effects') {
        return null;
    }
    const { sequenceSubscriptionKey } = selection.nodePathInfo;
    const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(sequenceSubscriptionKey)];
    if (!sequenceStatus || !sequenceStatus.canUpdate) {
        return null;
    }
    const effects = selection.type === 'sequence-effect'
        ? sequenceStatus.effects.filter((effect) => effect.effectIndex === selection.i)
        : sequenceStatus.effects;
    if (selection.type === 'sequence-effect' && effects.length !== 1) {
        return null;
    }
    const snapshots = [];
    for (const effect of effects) {
        if (!effect.canUpdate) {
            return null;
        }
        const snapshot = effectStatusToSnapshot(effect);
        if (snapshot === null) {
            return null;
        }
        snapshots.push(snapshot);
    }
    return snapshots;
};
exports.getSnapshotsFromSelection = getSnapshotsFromSelection;
const getEffectClipboardDataFromSelections = ({ selectedItems, propStatuses, }) => {
    const firstSelection = selectedItems[0];
    const type = firstSelection ? getCopyType(firstSelection) : null;
    if (type === null) {
        return { type: 'none' };
    }
    if (selectedItems.some((selection) => getCopyType(selection) !== type)) {
        return { type: 'mixed' };
    }
    const snapshots = selectedItems.flatMap((selection) => {
        const itemSnapshots = (0, exports.getSnapshotsFromSelection)({
            selection,
            propStatuses,
        });
        return itemSnapshots !== null && itemSnapshots !== void 0 ? itemSnapshots : [null];
    });
    if (snapshots.some((snapshot) => snapshot === null)) {
        return { type: 'uncopyable' };
    }
    return {
        type: 'valid',
        payload: {
            type,
            version: 3,
            remotionClipboard: 'effects',
            effects: snapshots,
        },
    };
};
exports.getEffectClipboardDataFromSelections = getEffectClipboardDataFromSelections;
const getEffectsClipboardEnvelopeFromSelections = ({ selectedItems, payload, }) => {
    if (payload.type !== 'effects-additive' ||
        selectedItems.some((selection) => selection.type !== 'sequence-effect')) {
        return {
            envelopeVersion: 1,
            payload,
            sourceIdentity: null,
            originalEffectIndices: [],
        };
    }
    const effectSelections = selectedItems;
    const firstSelection = effectSelections[0];
    if (!firstSelection || effectSelections.length !== payload.effects.length) {
        return {
            envelopeVersion: 1,
            payload,
            sourceIdentity: null,
            originalEffectIndices: [],
        };
    }
    const sourceIdentity = makeTargetKey(firstSelection.nodePathInfo.sequenceSubscriptionKey);
    if (effectSelections.some((selection) => makeTargetKey(selection.nodePathInfo.sequenceSubscriptionKey) !==
        sourceIdentity)) {
        return {
            envelopeVersion: 1,
            payload,
            sourceIdentity: null,
            originalEffectIndices: [],
        };
    }
    const indexedEffects = effectSelections
        .map((selection, index) => ({
        effectIndex: selection.i,
        effect: payload.effects[index],
    }))
        .sort((a, b) => a.effectIndex - b.effectIndex);
    return {
        envelopeVersion: 1,
        payload: {
            ...payload,
            effects: indexedEffects.map(({ effect }) => effect),
        },
        sourceIdentity,
        originalEffectIndices: indexedEffects.map(({ effectIndex }) => effectIndex),
    };
};
exports.getEffectsClipboardEnvelopeFromSelections = getEffectsClipboardEnvelopeFromSelections;
const getEffectPropClipboardDataFromSelection = ({ selection, propStatuses, }) => {
    if (selection.type !== 'sequence-effect-prop') {
        return null;
    }
    const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(selection.nodePathInfo.sequenceSubscriptionKey)];
    if (!sequenceStatus || !sequenceStatus.canUpdate) {
        return null;
    }
    const effect = sequenceStatus.effects.find((item) => item.effectIndex === selection.i);
    if (!(effect === null || effect === void 0 ? void 0 : effect.canUpdate) || effect.importPath === null) {
        return null;
    }
    const prop = effect.props[selection.key];
    if (!prop) {
        return null;
    }
    const param = effectPropStatusToClipboardParam(prop);
    if (param === null) {
        return null;
    }
    return {
        type: 'effect-prop',
        version: 1,
        remotionClipboard: 'effect-prop',
        effect: {
            callee: effect.callee,
            importPath: effect.importPath,
        },
        key: selection.key,
        param,
    };
};
exports.getEffectPropClipboardDataFromSelection = getEffectPropClipboardDataFromSelection;
const getEasingClipboardDataFromSelection = ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }) => {
    const easing = (0, update_selected_easing_1.getTimelineEasingValueForSelection)({
        selection,
        sequences,
        overrideIdsToNodePaths,
        propStatuses,
    });
    if (easing === null) {
        return null;
    }
    return {
        type: 'easing',
        version: 1,
        remotionClipboard: 'easing',
        easing,
    };
};
exports.getEasingClipboardDataFromSelection = getEasingClipboardDataFromSelection;
const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
    var _a;
    if (selectedItems.length === 0) {
        return { type: 'none' };
    }
    if (selectedItems.length !== 1) {
        return { type: 'multiple' };
    }
    const [selection] = selectedItems;
    if (!selection) {
        return { type: 'none' };
    }
    if (selection.type !== 'sequence-effect-prop' &&
        selection.type !== 'sequence-effect') {
        return { type: 'none' };
    }
    const target = selection.type === 'sequence-effect-prop'
        ? {
            effectIndex: selection.i,
            fieldKey: selection.key,
        }
        : {
            effectIndex: selection.i,
            fieldKey: payload.key,
        };
    if (!selection.nodePathInfo.supportsEffects) {
        return { type: 'unsupported' };
    }
    if (selection.type === 'sequence-effect-prop' &&
        selection.key !== payload.key) {
        return { type: 'prop-mismatch' };
    }
    const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
        sequences,
        overrideIdsToNodePaths,
        nodePathInfo: selection.nodePathInfo,
    });
    const sequence = (_a = track === null || track === void 0 ? void 0 : track.sequence) !== null && _a !== void 0 ? _a : null;
    if (!sequence) {
        return { type: 'none' };
    }
    const effect = sequence.effects[target.effectIndex];
    const fieldSchema = effect === null || effect === void 0 ? void 0 : effect.schema[target.fieldKey];
    if (!effect || !isVisibleFieldSchema(fieldSchema)) {
        return { type: 'prop-mismatch' };
    }
    const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(selection.nodePathInfo.sequenceSubscriptionKey)];
    if (!(sequenceStatus === null || sequenceStatus === void 0 ? void 0 : sequenceStatus.canUpdate)) {
        return { type: 'uncopyable' };
    }
    const effectStatus = sequenceStatus.effects.find((item) => item.effectIndex === target.effectIndex);
    if (!(effectStatus === null || effectStatus === void 0 ? void 0 : effectStatus.canUpdate)) {
        return { type: 'uncopyable' };
    }
    if (effectStatus.importPath !== payload.effect.importPath) {
        return { type: 'effect-type-mismatch' };
    }
    const propStatus = effectStatus.props[target.fieldKey];
    if (!propStatus || propStatus.status === 'computed') {
        return { type: 'uncopyable' };
    }
    return {
        type: 'valid',
        fileName: selection.nodePathInfo.sequenceSubscriptionKey.absolutePath,
        nodePath: selection.nodePathInfo.sequenceSubscriptionKey,
        effectIndex: target.effectIndex,
        fieldKey: target.fieldKey,
        defaultValue: getDefaultValue(fieldSchema),
        schema: effect.schema,
    };
};
exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
const TimelineClipboardKeybindings = () => {
    const keybindings = (0, use_keybinding_1.useKeybinding)();
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
    const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
    const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
    const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
    const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
    const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
    const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
    (0, react_1.useEffect)(() => {
        if (!canSelect || previewServerState.type !== 'connected') {
            return;
        }
        const { clientId } = previewServerState;
        const copy = keybindings.registerKeybinding({
            event: 'keydown',
            key: 'c',
            callback: (e) => {
                var _a;
                const { selectedItems } = currentSelection.current;
                const propStatuses = propStatusesRef.current;
                const sequences = sequencesRef.current;
                if (selectedItems.length === 0) {
                    return;
                }
                const easingSelections = (0, update_selected_easing_1.getEasingSelections)(selectedItems);
                if (easingSelections.length > 0) {
                    e.preventDefault();
                    if (easingSelections.length !== 1 ||
                        easingSelections.length !== selectedItems.length) {
                        (0, NotificationCenter_1.showNotification)('Select one easing to copy', 3000);
                        return;
                    }
                    const payload = (0, exports.getEasingClipboardDataFromSelection)({
                        selection: easingSelections[0],
                        sequences,
                        overrideIdsToNodePaths: overrideIdToNodePathMappings,
                        propStatuses,
                    });
                    if (payload === null) {
                        (0, NotificationCenter_1.showNotification)('Cannot copy easing because it cannot be read', 3000);
                        return;
                    }
                    navigator.clipboard
                        .writeText(makeClipboardText(payload))
                        .then(() => {
                        (0, NotificationCenter_1.showNotification)('Copied easing to clipboard', 1000);
                    })
                        .catch((err) => {
                        (0, NotificationCenter_1.showNotification)(`Could not copy easing: ${err.message}`, 2000);
                    });
                    return;
                }
                if (selectedItems.some((selection) => selection.type === 'sequence-effect-prop')) {
                    e.preventDefault();
                    if (selectedItems.length !== 1 ||
                        ((_a = selectedItems[0]) === null || _a === void 0 ? void 0 : _a.type) !== 'sequence-effect-prop') {
                        (0, NotificationCenter_1.showNotification)('Select one effect prop to copy its value', 3000);
                        return;
                    }
                    const payload = (0, exports.getEffectPropClipboardDataFromSelection)({
                        selection: selectedItems[0],
                        propStatuses,
                    });
                    if (payload === null) {
                        (0, NotificationCenter_1.showNotification)('Cannot copy effect prop because its value cannot be copied', 3000);
                        return;
                    }
                    navigator.clipboard
                        .writeText(makeClipboardText(payload))
                        .then(() => {
                        (0, NotificationCenter_1.showNotification)('Copied effect prop to clipboard', 1000);
                    })
                        .catch((err) => {
                        (0, NotificationCenter_1.showNotification)(`Could not copy effect prop: ${err.message}`, 2000);
                    });
                    return;
                }
                const effectClipboardData = (0, exports.getEffectClipboardDataFromSelections)({
                    selectedItems,
                    propStatuses,
                });
                if (effectClipboardData.type === 'none') {
                    return;
                }
                if (effectClipboardData.type === 'mixed') {
                    e.preventDefault();
                    (0, NotificationCenter_1.showNotification)('Cannot copy individual effects together with all effects', 3000);
                    return;
                }
                if (effectClipboardData.type === 'uncopyable') {
                    e.preventDefault();
                    (0, NotificationCenter_1.showNotification)('Cannot copy effects because one of them contains values that cannot be copied', 3000);
                    return;
                }
                e.preventDefault();
                navigator.clipboard
                    .writeText(makeClipboardText(effectClipboardData.payload))
                    .then(() => {
                    (0, NotificationCenter_1.showNotification)(effectClipboardData.payload.effects.length === 1
                        ? 'Copied effect to clipboard'
                        : 'Copied effects to clipboard', 1000);
                })
                    .catch((err) => {
                    (0, NotificationCenter_1.showNotification)(`Could not copy effects: ${err.message}`, 2000);
                });
            },
            commandCtrlKey: true,
            preventDefault: false,
            triggerIfInputFieldFocused: false,
            keepRegisteredWhenNotHighestContext: false,
        });
        const cut = keybindings.registerKeybinding({
            event: 'keydown',
            key: 'x',
            callback: (e) => {
                const { selectedItems, clearSelection, selectItems } = currentSelection.current;
                if (selectedItems.length === 0) {
                    return;
                }
                const effectClipboardData = (0, exports.getEffectClipboardDataFromSelections)({
                    selectedItems,
                    propStatuses: propStatusesRef.current,
                });
                if (effectClipboardData.type === 'none') {
                    return;
                }
                e.preventDefault();
                if (effectClipboardData.type === 'mixed') {
                    (0, NotificationCenter_1.showNotification)('Cannot cut individual effects together with all effects', 3000);
                    return;
                }
                if (effectClipboardData.type === 'uncopyable') {
                    (0, NotificationCenter_1.showNotification)('Cannot cut effects because one of them contains values that cannot be copied', 3000);
                    return;
                }
                const envelope = (0, exports.getEffectsClipboardEnvelopeFromSelections)({
                    selectedItems,
                    payload: effectClipboardData.payload,
                });
                const propStatuses = propStatusesRef.current;
                (0, effects_clipboard_1.writeEffectsClipboardEnvelope)(envelope)
                    .then(() => {
                    const deletePromise = (0, delete_selected_timeline_item_1.deleteSelectedTimelineItems)({
                        selections: selectedItems,
                        sequences: sequencesRef.current,
                        overrideIdsToNodePaths: overrideIdToNodePathMappings,
                        setPropStatuses,
                        clientId,
                        confirm,
                    });
                    return deletePromise === null || deletePromise === void 0 ? void 0 : deletePromise.then((deleted) => {
                        if (!deleted) {
                            return;
                        }
                        const nextSelection = (0, delete_selected_timeline_item_1.getTimelineSelectionAfterDeletingItems)({
                            selections: selectedItems,
                            propStatuses,
                        });
                        if (nextSelection.length === 0) {
                            clearSelection();
                        }
                        else {
                            selectItems(nextSelection);
                        }
                    });
                })
                    .catch((err) => {
                    (0, NotificationCenter_1.showNotification)(`Could not cut effects: ${err.message}`, 2000);
                });
            },
            commandCtrlKey: true,
            preventDefault: false,
            triggerIfInputFieldFocused: false,
            keepRegisteredWhenNotHighestContext: false,
        });
        const handlePaste = (e) => {
            const { activeElement } = document;
            if (activeElement instanceof HTMLInputElement ||
                activeElement instanceof HTMLTextAreaElement) {
                return;
            }
            const { selectedItems } = currentSelection.current;
            if (selectedItems.length === 0 || e.clipboardData === null) {
                return;
            }
            e.preventDefault();
            const { text, envelope } = (0, effects_clipboard_1.readClipboardTextAndEffectsEnvelope)(e.clipboardData);
            Promise.resolve()
                .then(() => {
                const propStatuses = propStatusesRef.current;
                const sequences = sequencesRef.current;
                const easingResult = (0, studio_shared_1.parseEasingClipboardDataResult)(text);
                if (easingResult.status !== 'invalid') {
                    e.preventDefault();
                    if (easingResult.status === 'unsupported-version') {
                        (0, NotificationCenter_1.showNotification)('Cannot paste easing copied from a different Remotion Studio version', 4000);
                        return;
                    }
                    const easingSelections = (0, update_selected_easing_1.getEasingSelections)(selectedItems);
                    if (easingSelections.length === 0 ||
                        easingSelections.length !== selectedItems.length) {
                        (0, NotificationCenter_1.showNotification)('Select an easing to paste onto', 3000);
                        return;
                    }
                    const updatePromise = (0, update_selected_easing_1.updateSelectedTimelineEasings)({
                        selections: easingSelections,
                        sequences,
                        overrideIdsToNodePaths: overrideIdToNodePathMappings,
                        propStatuses,
                        setPropStatuses,
                        clientId,
                        easing: easingResult.data.easing,
                    });
                    if (updatePromise === null) {
                        (0, NotificationCenter_1.showNotification)('Cannot paste onto an easing that cannot be updated', 3000);
                        return;
                    }
                    return updatePromise
                        .then(() => {
                        (0, NotificationCenter_1.showNotification)(easingSelections.length === 1
                            ? 'Pasted easing'
                            : 'Pasted easing to selected segments', 2000);
                    })
                        .catch((err) => {
                        (0, NotificationCenter_1.showNotification)(`Could not paste easing: ${err.message}`, 3000);
                    });
                }
                const effectPropResult = (0, studio_shared_1.parseEffectPropClipboardDataResult)(text);
                if (effectPropResult.status !== 'invalid') {
                    e.preventDefault();
                    if (effectPropResult.status === 'unsupported-version') {
                        (0, NotificationCenter_1.showNotification)('Cannot paste effect prop copied from a different Remotion Studio version', 4000);
                        return;
                    }
                    const effectPropTarget = (0, exports.getPasteEffectPropTarget)({
                        selectedItems,
                        payload: effectPropResult.data,
                        propStatuses,
                        sequences,
                        overrideIdsToNodePaths: overrideIdToNodePathMappings,
                    });
                    if (effectPropTarget.type !== 'valid') {
                        switch (effectPropTarget.type) {
                            case 'multiple':
                                (0, NotificationCenter_1.showNotification)('Select one target effect prop or effect to paste onto', 3000);
                                return;
                            case 'none':
                                (0, NotificationCenter_1.showNotification)('Select a matching effect prop or effect to paste onto', 3000);
                                return;
                            case 'unsupported':
                                (0, NotificationCenter_1.showNotification)('This sequence does not support effects', 3000);
                                return;
                            case 'effect-type-mismatch':
                                (0, NotificationCenter_1.showNotification)('Select an effect of the same type to paste this prop', 3000);
                                return;
                            case 'prop-mismatch':
                                (0, NotificationCenter_1.showNotification)('Select the same effect prop, or an effect with that prop', 3000);
                                return;
                            case 'uncopyable':
                                (0, NotificationCenter_1.showNotification)('Cannot paste onto an effect prop that cannot be updated', 3000);
                                return;
                            default:
                                throw new Error(`Unexpected paste target: ${effectPropTarget}`);
                        }
                    }
                    return (0, save_effect_prop_1.saveEffectProp)({
                        fileName: effectPropTarget.fileName,
                        nodePath: effectPropTarget.nodePath,
                        effectIndex: effectPropTarget.effectIndex,
                        fieldKey: effectPropTarget.fieldKey,
                        ...(effectPropResult.data.param.type === 'static'
                            ? {
                                type: 'value',
                                value: effectPropResult.data.param.value,
                            }
                            : {
                                type: 'effect-param',
                                effectParam: effectPropResult.data.param,
                            }),
                        defaultValue: effectPropTarget.defaultValue,
                        schema: effectPropTarget.schema,
                        setPropStatuses,
                        clientId,
                    }).then(() => {
                        (0, NotificationCenter_1.showNotification)('Pasted effect prop', 2000);
                    });
                }
                const result = envelope === null
                    ? (0, studio_shared_1.parseEffectClipboardDataResult)(text)
                    : { status: 'valid', data: envelope.payload };
                if (result.status === 'invalid') {
                    return;
                }
                e.preventDefault();
                if (result.status === 'unsupported-version') {
                    (0, NotificationCenter_1.showNotification)('Cannot paste effects copied from a different Remotion Studio version', 4000);
                    return;
                }
                const { data: payload } = result;
                const target = (0, exports.getPasteEffectsTarget)(selectedItems);
                if (target.type === 'multiple') {
                    (0, NotificationCenter_1.showNotification)('Select one target sequence to paste effects', 3000);
                    return;
                }
                if (target.type === 'none') {
                    (0, NotificationCenter_1.showNotification)('Select a sequence to paste effects onto', 3000);
                    return;
                }
                if (target.type === 'unsupported') {
                    (0, NotificationCenter_1.showNotification)('This sequence does not support effects', 3000);
                    return;
                }
                const { sequenceSubscriptionKey: targetSequenceNodePath } = target.nodePathInfo;
                const insertAtIndices = (envelope === null || envelope === void 0 ? void 0 : envelope.sourceIdentity) === makeTargetKey(targetSequenceNodePath)
                    ? envelope.originalEffectIndices
                    : null;
                return (0, call_api_1.callApi)('/api/paste-effects', {
                    targetFileName: targetSequenceNodePath.absolutePath,
                    targetSequenceNodePath,
                    type: payload.type,
                    effects: payload.effects,
                    clientId,
                    insertAtIndices,
                }).then((pasteResult) => {
                    if (pasteResult.success) {
                        (0, NotificationCenter_1.showNotification)('Pasted effects', 2000);
                    }
                    else {
                        (0, NotificationCenter_1.showNotification)(pasteResult.reason, 4000);
                    }
                });
            })
                .catch((err) => {
                (0, NotificationCenter_1.showNotification)(`Could not paste effects: ${err.message}`, 3000);
            });
        };
        // Reading ClipboardEvent data avoids the permission prompt caused by
        // navigator.clipboard.read().
        if (keybindings.isHighestContext && !(0, use_keybinding_1.areKeyboardShortcutsDisabled)()) {
            document.addEventListener('paste', handlePaste);
        }
        return () => {
            copy.unregister();
            cut.unregister();
            document.removeEventListener('paste', handlePaste);
        };
    }, [
        canSelect,
        confirm,
        currentSelection,
        keybindings,
        overrideIdToNodePathMappings,
        propStatusesRef,
        previewServerState,
        sequencesRef,
        setPropStatuses,
    ]);
    return null;
};
exports.TimelineClipboardKeybindings = TimelineClipboardKeybindings;
