"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtensionTabBarTreeView = void 0;
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importStar(require("react"));
const ide_components_1 = require("@opensumi/ide-components");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const progress_bar_1 = require("@opensumi/ide-core-browser/lib/progress/progress-bar");
const ide_decoration_1 = require("@opensumi/ide-decoration");
const welcome_view_1 = require("@opensumi/ide-main-layout/lib/browser/welcome.view");
const main_layout_definition_1 = require("@opensumi/ide-main-layout/lib/common/main-layout.definition");
const extension_tree_view_node_1 = require("./extension-tree-view-node");
const extension_tree_view_module_less_1 = tslib_1.__importDefault(require("./extension-tree-view.module.less"));
const ExtensionTabBarTreeView = ({ viewState, model, dataProvider, treeViewId, }) => {
    const layoutService = (0, ide_core_browser_1.useInjectable)(main_layout_definition_1.IMainLayoutService);
    const decorationService = (0, ide_core_browser_1.useInjectable)(ide_decoration_1.IDecorationsService);
    const accordionService = (0, react_1.useMemo)(() => layoutService.getViewAccordionService(treeViewId), []);
    const isVisible = (0, react_1.useMemo)(() => {
        const state = accordionService === null || accordionService === void 0 ? void 0 : accordionService.getViewState(treeViewId);
        if (!state) {
            return false;
        }
        return !state.collapsed && !state.hidden;
    }, [accordionService]);
    const { height } = viewState;
    const { canSelectMany } = model.treeViewOptions || {};
    const wrapperRef = (0, react_1.useRef)(null);
    const handleTreeReady = (0, react_1.useCallback)((handle) => {
        model.handleTreeHandler({
            ...handle,
            getModel: () => model.treeModel,
            hasDirectFocus: () => wrapperRef.current === document.activeElement,
        });
    }, [model]);
    const handleTwistierClick = (0, react_1.useCallback)((ev, item) => {
        // 阻止点击事件冒泡
        ev.stopPropagation();
        const { toggleDirectory } = model;
        toggleDirectory(item);
    }, [model]);
    const hasShiftMask = (0, react_1.useCallback)((event) => {
        // Ctrl/Cmd 权重更高
        if (hasCtrlCmdMask(event)) {
            return false;
        }
        return event.shiftKey;
    }, []);
    const hasCtrlCmdMask = (0, react_1.useCallback)((event) => {
        const { metaKey, ctrlKey } = event;
        return (ide_core_browser_1.isOSX && metaKey) || ctrlKey;
    }, []);
    const handleItemClicked = (0, react_1.useCallback)((ev, item, type) => {
        // 阻止点击事件冒泡
        ev.stopPropagation();
        const { handleItemClick, handleItemToggleClick, handleItemRangeClick } = model;
        if (!item) {
            return;
        }
        const shiftMask = hasShiftMask(event);
        const ctrlCmdMask = hasCtrlCmdMask(event);
        if (canSelectMany) {
            if (shiftMask) {
                handleItemRangeClick(item, type);
            }
            else if (ctrlCmdMask) {
                handleItemToggleClick(item, type);
            }
            else {
                handleItemClick(item, type);
            }
        }
        else {
            handleItemClick(item, type);
        }
    }, [canSelectMany, model]);
    const handleCheckBoxChange = (0, react_1.useCallback)((item) => {
        const { handleCheckBoxChange } = model;
        if (item) {
            handleCheckBoxChange(item);
        }
    }, [model]);
    const handleContextMenu = (0, react_1.useCallback)((ev, node) => {
        const { handleContextMenu } = model;
        handleContextMenu(ev, node);
    }, [model]);
    const handleOuterContextMenu = (ev) => {
        const { handleContextMenu } = model;
        // 空白区域右键菜单
        handleContextMenu(ev);
    };
    const handleOuterClick = (0, react_1.useCallback)(() => {
        // 空白区域点击，取消焦点状态
        const { enactiveNodeDecoration } = model;
        enactiveNodeDecoration();
    }, [model]);
    const handleDragStart = (0, react_1.useCallback)((ev, node) => {
        const { handleDragStart } = model;
        handleDragStart(ev, node);
    }, [model]);
    const handleDragOver = (0, react_1.useCallback)((ev, node) => {
        const { handleDragOver } = model;
        handleDragOver(ev, node);
    }, [model]);
    const handleDragEnter = (0, react_1.useCallback)((ev, node) => {
        const { handleDragEnter } = model;
        handleDragEnter(ev, node);
    }, [model]);
    const handleDrop = (0, react_1.useCallback)((ev, node) => {
        const { handleDrop } = model;
        handleDrop(ev, node);
    }, [model]);
    const handleDragLeave = (0, react_1.useCallback)((ev, node) => {
        const { handleDragLeave } = model;
        handleDragLeave(ev, node);
    }, [model]);
    (0, react_1.useEffect)(() => {
        var _a;
        const handleBlur = () => {
            model.handleTreeBlur();
        };
        (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('blur', handleBlur, true);
        return () => {
            var _a;
            (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('blur', handleBlur, true);
        };
    }, [wrapperRef.current]);
    return (react_1.default.createElement("div", { className: extension_tree_view_module_less_1.default.kt_extension_view, tabIndex: -1, ref: wrapperRef, onContextMenu: handleOuterContextMenu, onClick: handleOuterClick, "data-tree-view-id": treeViewId },
        react_1.default.createElement(TreeView, { height: height, isVisible: isVisible, handleTreeReady: handleTreeReady, handleItemClicked: handleItemClicked, handleCheckBoxChange: handleCheckBoxChange, handleTwistierClick: handleTwistierClick, handleContextMenu: handleContextMenu, handleDragStart: handleDragStart, handleDragOver: handleDragOver, handleDragEnter: handleDragEnter, handleDragLeave: handleDragLeave, handleDrop: handleDrop, draggable: model.draggable, treeViewId: treeViewId, model: model, dataProvider: dataProvider, decorationService: decorationService })));
};
exports.ExtensionTabBarTreeView = ExtensionTabBarTreeView;
function isTreeViewPropsEqual(prevProps, nextProps) {
    return (prevProps.isVisible === nextProps.isVisible &&
        prevProps.model === nextProps.model &&
        prevProps.treeViewId === nextProps.treeViewId &&
        prevProps.height === nextProps.height);
}
const TreeView = (0, react_1.memo)(({ model, treeViewId, height, isVisible, dataProvider, handleTreeReady, handleItemClicked, handleCheckBoxChange, handleTwistierClick, handleContextMenu, handleDragStart, handleDragOver, handleDragEnter, handleDragLeave, handleDrop, draggable, decorationService, }) => {
    const [isReady, setIsReady] = (0, react_1.useState)(false);
    const [isEmpty, setIsEmpty] = (0, react_1.useState)(false);
    (0, react_1.useEffect)(() => {
        let unmouted = false;
        (async () => {
            await model.whenReady;
            if (model.treeModel && isVisible) {
                await model.treeModel.ensureReady;
            }
            if (!unmouted) {
                setIsReady(true);
            }
        })();
        return () => {
            unmouted = true;
            model && model.removeNodeDecoration();
        };
    }, [model, isVisible]);
    (0, react_1.useEffect)(() => {
        const disposable = dataProvider.onDidChangeEmpty(() => {
            if (dataProvider.isTreeEmpty !== isEmpty) {
                setIsEmpty(dataProvider.isTreeEmpty);
            }
        });
        return () => disposable.dispose();
    }, []);
    const renderTreeNode = (0, react_1.useCallback)((props) => (react_1.default.createElement(extension_tree_view_node_1.TreeViewNode, { item: props.item, itemType: props.itemType, decorations: model.decorations.getDecorations(props.item), onClick: handleItemClicked, onChange: handleCheckBoxChange, onTwistierClick: handleTwistierClick, onContextMenu: handleContextMenu, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, defaultLeftPadding: 8, leftPadding: 8, treeViewId: treeViewId, draggable: draggable, decorationService: decorationService })), [model.treeModel]);
    if (!isReady) {
        return react_1.default.createElement(progress_bar_1.Progress, { loading: true });
    }
    else if (isEmpty) {
        return react_1.default.createElement(welcome_view_1.WelcomeView, { viewId: treeViewId });
    }
    else {
        if (model.treeModel) {
            return (react_1.default.createElement(ide_components_1.RecycleTree, { height: height, itemHeight: extension_tree_view_node_1.TREE_VIEW_NODE_HEIGHT, onReady: handleTreeReady, model: model.treeModel }, renderTreeNode));
        }
    }
    return null;
}, isTreeViewPropsEqual);
TreeView.displayName = 'ExtensionsTreeView';
//# sourceMappingURL=extension-tree-view.js.map