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 += ``;
if (view.coverFrom !== 0) {
if (item.coverURL) {
if (item.coverURL.startsWith("background")) {
galleryHTML += `
`;
} else {
galleryHTML += `
`;
}
} else if (item.coverContent) {
galleryHTML += `
`;
} else {
galleryHTML += '
';
}
}
galleryHTML += `
`;
item.values.forEach((cell, fieldsIndex) => {
if (view.fields[fieldsIndex].hidden) {
return;
}
let checkClass = "";
if (cell.valueType === "checkbox") {
checkClass = cell.value?.checkbox?.checked ? " av__cell-check" : " av__cell-uncheck";
}
const isEmpty = cellValueIsEmpty(cell.value);
galleryHTML += `
${renderCell(cell.value, rowIndex, view.showIcon, "gallery")}
`;
});
galleryHTML += `
`;
});
galleryHTML += `${window.siyuan.languages.addCard}
`;
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 = `
${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);
}
});
});
};