import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../../../util/hasClosest"; import {Constants} from "../../../../constants"; import {fetchPost} from "../../../../util/fetch"; import {escapeAriaLabel, escapeAttr, escapeHtml} from "../../../../util/escape"; import {unicode2Emoji} from "../../../../emoji"; import {cellValueIsEmpty, renderCell} from "../cell"; import {focusBlock} from "../../../util/selection"; import {electronUndo} from "../../../undo"; import {addClearButton} from "../../../../util/addClearButton"; import {updateSearch} from "../render"; import {getViewIcon} from "../view"; export const renderGallery = (options: { blockElement: HTMLElement, protyle: IProtyle, cb?: (data: IAV) => void, viewID?: string, renderAll: boolean }) => { const alignSelf = options.blockElement.style.alignSelf; let oldOffset: number; if (options.blockElement.firstElementChild.innerHTML === "") { options.blockElement.style.alignSelf = ""; options.blockElement.firstElementChild.outerHTML = ``; } else { oldOffset = options.protyle.contentElement.scrollTop; } const editIds: string[] = []; options.blockElement.querySelectorAll(".av__gallery-fields--edit").forEach(item => { editIds.push(item.parentElement.getAttribute("data-id")); }); const selectItemIds: string[] = []; options.blockElement.querySelectorAll(".av__gallery-item--select").forEach(rowItem => { const rowId = rowItem.getAttribute("data-id"); if (rowId) { selectItemIds.push(rowId); } }); const created = options.protyle.options.history?.created; const snapshot = options.protyle.options.history?.snapshot; let newViewID = options.blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW) || ""; if (typeof options.viewID === "string") { const viewTabElement = options.blockElement.querySelector(`.av__views > .layout-tab-bar > .item[data-id="${options.viewID}"]`) as HTMLElement; if (viewTabElement) { options.blockElement.dataset.pageSize = viewTabElement.dataset.page; } newViewID = options.viewID; fetchPost("/api/av/setDatabaseBlockView", { id: options.blockElement.dataset.nodeId, avID: options.blockElement.dataset.avId, viewID: options.viewID }); options.blockElement.setAttribute(Constants.CUSTOM_SY_AV_VIEW, newViewID); } let searchInputElement = options.blockElement.querySelector('[data-type="av-search"]') as HTMLInputElement; const isSearching = searchInputElement && document.activeElement.isSameNode(searchInputElement); const query = searchInputElement?.value || ""; fetchPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), { id: options.blockElement.getAttribute("data-av-id"), created, snapshot, pageSize: parseInt(options.blockElement.dataset.pageSize) || undefined, viewID: newViewID, query: query.trim() }, (response) => { const view: IAVGallery = response.data.view; if (!options.blockElement.dataset.pageSize) { options.blockElement.dataset.pageSize = view.pageSize.toString(); } let galleryHTML = ""; // body view.cards.forEach((item: IAVGalleryItem, rowIndex: number) => { galleryHTML += ``; }); galleryHTML += ``; let tabHTML = ""; let viewData: IAVView; response.data.views.forEach((item: IAVView) => { tabHTML += `
${item.icon ? unicode2Emoji(item.icon, "item__graphic", true) : ``} ${escapeHtml(item.name)}
`; if (item.id === response.data.viewID) { viewData = item; } }); if (options.renderAll) { options.blockElement.firstElementChild.outerHTML = `
${tabHTML}
${response.data.views.length}
${response.data.isMirror ? `
` : ""}
${response.data.name || ""}
${galleryHTML}
${Constants.ZWSP}
`; } else { const galleryElement = options.blockElement.firstElementChild.querySelector(".av__gallery"); galleryElement.innerHTML = galleryHTML; if (view.hideAttrViewName) { galleryElement.classList.add("av__gallery--top"); } else { galleryElement.classList.remove("av__gallery--top"); } } if (typeof oldOffset === "number") { options.protyle.contentElement.scrollTop = oldOffset; } options.blockElement.setAttribute("data-render", "true"); if (alignSelf) { options.blockElement.style.alignSelf = alignSelf; } if (getSelection().rangeCount > 0) { // 修改表头后光标重新定位 const range = getSelection().getRangeAt(0); if (!hasClosestByClassName(range.startContainer, "av__title")) { const blockElement = hasClosestBlock(range.startContainer); if (blockElement && options.blockElement.isSameNode(blockElement) && !isSearching) { focusBlock(options.blockElement); } } } options.blockElement.querySelector(".layout-tab-bar").scrollLeft = (options.blockElement.querySelector(".layout-tab-bar .item--focus") as HTMLElement).offsetLeft; if (options.cb) { options.cb(response.data); } if (!options.renderAll) { return; } const viewsElement = options.blockElement.querySelector(".av__views") as HTMLElement; searchInputElement = options.blockElement.querySelector('[data-type="av-search"]') as HTMLInputElement; searchInputElement.value = query || ""; if (isSearching) { searchInputElement.focus(); } searchInputElement.addEventListener("compositionstart", (event: KeyboardEvent) => { event.stopPropagation(); }); searchInputElement.addEventListener("keydown", (event: KeyboardEvent) => { if (event.isComposing) { return; } electronUndo(event); }); searchInputElement.addEventListener("input", (event: KeyboardEvent) => { event.stopPropagation(); if (event.isComposing) { return; } if (searchInputElement.value || document.activeElement.isSameNode(searchInputElement)) { viewsElement.classList.add("av__views--show"); } else { viewsElement.classList.remove("av__views--show"); } updateSearch(options.blockElement, options.protyle); }); searchInputElement.addEventListener("compositionend", () => { updateSearch(options.blockElement, options.protyle); }); searchInputElement.addEventListener("blur", (event: KeyboardEvent) => { if (event.isComposing) { return; } if (!searchInputElement.value) { viewsElement.classList.remove("av__views--show"); searchInputElement.style.width = "0"; searchInputElement.style.paddingLeft = "0"; searchInputElement.style.paddingRight = "0"; } }); addClearButton({ inputElement: searchInputElement, right: 0, width: "1em", height: searchInputElement.clientHeight, clearCB() { viewsElement.classList.remove("av__views--show"); searchInputElement.style.width = "0"; searchInputElement.style.paddingLeft = "0"; searchInputElement.style.paddingRight = "0"; focusBlock(options.blockElement); updateSearch(options.blockElement, options.protyle); } }); }); };