mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 09:30:14 +01:00
This commit is contained in:
parent
9da8f9b194
commit
3010df69b4
7 changed files with 360 additions and 42 deletions
|
|
@ -277,6 +277,10 @@
|
|||
gap: 16px;
|
||||
width: 100%;
|
||||
|
||||
&--top {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&--small {
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
}
|
||||
|
|
@ -293,11 +297,11 @@
|
|||
|
||||
&:hover {
|
||||
.av__gallery-cover {
|
||||
background-color: var(--b3-theme-surface-lighter);
|
||||
background-color: var(--b3-list-hover);
|
||||
}
|
||||
|
||||
.av__gallery-fields {
|
||||
background-color: var(--b3-theme-surface-light);
|
||||
background-color: var(--b3-theme-surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -336,6 +340,7 @@
|
|||
}
|
||||
|
||||
&-fields {
|
||||
border-radius: 0 0 var(--b3-border-radius) var(--b3-border-radius);
|
||||
flex: 1;
|
||||
transition: background 100ms ease-out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,13 +153,20 @@ ${cell.color ? `color:${cell.color};` : ""}">${renderCell(cell.value, rowIndex)}
|
|||
<div contenteditable="${options.protyle.disabled || hasClosestByAttribute(options.blockElement, "data-type", "NodeBlockQueryEmbed") ? "false" : "true"}" spellcheck="${window.siyuan.config.editor.spellcheck.toString()}" class="av__title${viewData.hideAttrViewName ? " fn__none" : ""}" data-title="${response.data.name || ""}" data-tip="${window.siyuan.languages.title}">${response.data.name || ""}</div>
|
||||
<div class="av__counter fn__none"></div>
|
||||
</div>
|
||||
<div class="av__gallery${view.cardSize === 0 ? " av__gallery--small" : (view.cardSize === 2 ? " av__gallery--big" : "")}">
|
||||
<div class="av__gallery${view.cardSize === 0 ? " av__gallery--small" : (view.cardSize === 2 ? " av__gallery--big" : "")}
|
||||
${view.hideAttrViewName ? " av__gallery--top" : ""}">
|
||||
${galleryHTML}
|
||||
</div>
|
||||
<div class="av__cursor" contenteditable="true">${Constants.ZWSP}</div>
|
||||
</div>`;
|
||||
} else {
|
||||
options.blockElement.firstElementChild.querySelector(".av__gallery").innerHTML = galleryHTML;
|
||||
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");
|
||||
}
|
||||
}
|
||||
options.blockElement.setAttribute("data-render", "true");
|
||||
if (alignSelf) {
|
||||
|
|
|
|||
171
app/src/protyle/render/av/gallery/util.ts
Normal file
171
app/src/protyle/render/av/gallery/util.ts
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import {transaction} from "../../../wysiwyg/transaction";
|
||||
import {Menu} from "../../../../plugin/Menu";
|
||||
|
||||
export const setGalleryCover = (options: {
|
||||
view: IAVGallery
|
||||
nodeElement: Element,
|
||||
protyle: IProtyle,
|
||||
target: HTMLElement
|
||||
}) => {
|
||||
const avID = options.nodeElement.getAttribute("data-av-id");
|
||||
const blockID = options.nodeElement.getAttribute("data-node-id");
|
||||
const targetNameElement = options.target.querySelector(".b3-menu__accelerator");
|
||||
const menu = new Menu();
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.coverFrom === 0,
|
||||
label: window.siyuan.languages.calcOperatorNone,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: 0
|
||||
}], [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.coverFrom
|
||||
}]);
|
||||
options.view.coverFrom = 0;
|
||||
targetNameElement.textContent = window.siyuan.languages.calcOperatorNone;
|
||||
}
|
||||
});
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.coverFrom === 1,
|
||||
label: window.siyuan.languages.contentImage,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: 1
|
||||
}], [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.coverFrom
|
||||
}]);
|
||||
options.view.coverFrom = 1;
|
||||
targetNameElement.textContent = window.siyuan.languages.contentImage;
|
||||
}
|
||||
});
|
||||
options.view.fields.forEach(item => {
|
||||
if (item.type === "mAsset") {
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.coverFromAssetKeyID === item.id,
|
||||
label: item.name,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: 2
|
||||
}, {
|
||||
action: "setAttrViewCoverFromAssetKeyID",
|
||||
avID,
|
||||
blockID,
|
||||
keyID: item.id
|
||||
}], [{
|
||||
action: "setAttrViewCoverFrom",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.coverFrom
|
||||
}, {
|
||||
action: "setAttrViewCoverFromAssetKeyID",
|
||||
avID,
|
||||
blockID,
|
||||
keyID: options.view.coverFromAssetKeyID
|
||||
}]);
|
||||
options.view.coverFrom = 2;
|
||||
options.view.coverFromAssetKeyID = item.id;
|
||||
targetNameElement.textContent = item.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const rect = options.target.getBoundingClientRect();
|
||||
menu.open({x: rect.left, y: rect.bottom});
|
||||
};
|
||||
|
||||
export const setGallerySize = (options: {
|
||||
view: IAVGallery
|
||||
nodeElement: Element,
|
||||
protyle: IProtyle,
|
||||
target: HTMLElement
|
||||
}) => {
|
||||
const menu = new Menu();
|
||||
const avID = options.nodeElement.getAttribute("data-av-id");
|
||||
const blockID = options.nodeElement.getAttribute("data-node-id");
|
||||
const galleryElement = options.nodeElement.querySelector(".av__gallery");
|
||||
const targetNameElement = options.target.querySelector(".b3-menu__accelerator");
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.cardSize === 0,
|
||||
label: window.siyuan.languages.small,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: 0
|
||||
}], [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.cardSize
|
||||
}]);
|
||||
options.view.cardSize = 0;
|
||||
galleryElement.classList.add("av__gallery--small");
|
||||
galleryElement.classList.remove("av__gallery--big");
|
||||
targetNameElement.textContent = window.siyuan.languages.small;
|
||||
}
|
||||
});
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.cardSize === 1,
|
||||
label: window.siyuan.languages.medium,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: 1
|
||||
}], [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.cardSize
|
||||
}]);
|
||||
options.view.cardSize = 1;
|
||||
galleryElement.classList.remove("av__gallery--big", "av__gallery--small");
|
||||
targetNameElement.textContent = window.siyuan.languages.medium;
|
||||
}
|
||||
});
|
||||
menu.addItem({
|
||||
iconHTML: "",
|
||||
checked: options.view.cardSize === 2,
|
||||
label: window.siyuan.languages.large,
|
||||
click() {
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: 2
|
||||
}], [{
|
||||
action: "setAttrViewCardSize",
|
||||
avID,
|
||||
blockID,
|
||||
data: options.view.cardSize
|
||||
}]);
|
||||
options.view.cardSize = 2;
|
||||
galleryElement.classList.remove("av__gallery--small");
|
||||
galleryElement.classList.add("av__gallery--big");
|
||||
targetNameElement.textContent = window.siyuan.languages.large;
|
||||
}
|
||||
});
|
||||
const rect = options.target.getBoundingClientRect();
|
||||
menu.open({x: rect.left, y: rect.bottom});
|
||||
};
|
||||
|
|
@ -2,13 +2,48 @@ import {transaction} from "../../wysiwyg/transaction";
|
|||
|
||||
export const getLayoutHTML = (data: IAV) => {
|
||||
let html = "";
|
||||
const view = data.view as IAVGallery;
|
||||
if (data.viewType === "gallery") {
|
||||
html = `<label class="b3-menu__item">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.showTitle}</span>
|
||||
let coverFromTitle = "";
|
||||
if (view.coverFrom === 0) {
|
||||
coverFromTitle = window.siyuan.languages.calcOperatorNone;
|
||||
} else if (view.coverFrom === 1) {
|
||||
coverFromTitle = window.siyuan.languages.contentImage;
|
||||
} else {
|
||||
view.fields.find(item => {
|
||||
if (item.type === "mAsset" && item.id === view.coverFromAssetKeyID) {
|
||||
coverFromTitle = item.name;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
html = `<button class="b3-menu__item" data-type="set-gallery-cover">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.cardPreview1}</span>
|
||||
<span class="fn__flex-1"></span>
|
||||
<span class="b3-menu__accelerator">${coverFromTitle}</span>
|
||||
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
|
||||
</button>
|
||||
<button class="b3-menu__item" data-type="set-gallery-size">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.cardSize}</span>
|
||||
<span class="fn__flex-1"></span>
|
||||
<span class="b3-menu__accelerator">${view.cardSize === 0 ? window.siyuan.languages.small : (view.cardSize === 1 ? window.siyuan.languages.medium : window.siyuan.languages.large)}</span>
|
||||
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
|
||||
</button>
|
||||
<label class="b3-menu__item">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.fitImage}</span>
|
||||
<span class="fn__space fn__flex-1"></span>
|
||||
<input data-type="toggle-view-title" type="checkbox" class="b3-switch b3-switch--menu" ${data.view.hideAttrViewName ? "" : "checked"}>
|
||||
</label>`
|
||||
// calcOperatorNone
|
||||
<input data-type="toggle-gallery-fit" type="checkbox" class="b3-switch b3-switch--menu" ${view.fitImage ? "checked" : ""}>
|
||||
</label>
|
||||
<label class="b3-menu__item">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.showIcon}</span>
|
||||
<span class="fn__space fn__flex-1"></span>
|
||||
<input data-type="toggle-gallery-icon" type="checkbox" class="b3-switch b3-switch--menu" ${view.showIcon ? "checked" : ""}>
|
||||
</label>
|
||||
<label class="b3-menu__item">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.wrapAllFields}</span>
|
||||
<span class="fn__space fn__flex-1"></span>
|
||||
<input data-type="toggle-gallery-wrap" type="checkbox" class="b3-switch b3-switch--menu" ${view.wrapField ? "checked" : ""}>
|
||||
</label>`;
|
||||
}
|
||||
return `<div class="b3-menu__items">
|
||||
<div class="b3-menu__items">
|
||||
|
|
@ -21,12 +56,12 @@ export const getLayoutHTML = (data: IAV) => {
|
|||
<button class="b3-menu__separator"></button>
|
||||
<button class="b3-menu__item" data-type="nobg">
|
||||
<div class="av__layout">
|
||||
<div class="av__layout-item${data.viewType === "table" ? " av__layout-item--select" : ""}">
|
||||
<div data-type="set-layoyt" data-view-type="${data.viewType}" class="av__layout-item${data.viewType === "table" ? " av__layout-item--select" : ""}">
|
||||
<svg><use xlink:href="#iconTable"></use></svg>
|
||||
<div class="fn__hr"></div>
|
||||
<div>${window.siyuan.languages.table}</div>
|
||||
</div>
|
||||
<div class="av__layout-item${data.viewType === "gallery" ? " av__layout-item--select" : ""}">
|
||||
<div data-type="set-layoyt" data-view-type="${data.viewType}" class="av__layout-item${data.viewType === "gallery" ? " av__layout-item--select" : ""}">
|
||||
<svg><use xlink:href="#iconGallery"></use></svg>
|
||||
<div class="fn__hr"></div>
|
||||
<div>${window.siyuan.languages.gallery}</div>
|
||||
|
|
@ -36,7 +71,7 @@ export const getLayoutHTML = (data: IAV) => {
|
|||
<label class="b3-menu__item">
|
||||
<span class="fn__flex-center">${window.siyuan.languages.showTitle}</span>
|
||||
<span class="fn__space fn__flex-1"></span>
|
||||
<input data-type="toggle-view-title" type="checkbox" class="b3-switch b3-switch--menu" ${data.view.hideAttrViewName ? "" : "checked"}>
|
||||
<input data-type="toggle-view-title" type="checkbox" class="b3-switch b3-switch--menu" ${view.hideAttrViewName ? "" : "checked"}>
|
||||
</label>
|
||||
${html}
|
||||
</div>`;
|
||||
|
|
@ -52,33 +87,93 @@ export const bindLayoutEvent = (options: {
|
|||
toggleTitleElement.addEventListener("change", () => {
|
||||
const avID = options.blockElement.getAttribute("data-av-id");
|
||||
const blockID = options.blockElement.getAttribute("data-node-id");
|
||||
if (!toggleTitleElement.checked) {
|
||||
// hide
|
||||
const checked = toggleTitleElement.checked;
|
||||
transaction(options.protyle, [{
|
||||
action: "hideAttrViewName",
|
||||
avID,
|
||||
blockID,
|
||||
data: true
|
||||
data: !checked
|
||||
}], [{
|
||||
action: "hideAttrViewName",
|
||||
avID,
|
||||
blockID,
|
||||
data: false
|
||||
}]);
|
||||
options.blockElement.querySelector(".av__title").classList.add("fn__none");
|
||||
} else {
|
||||
transaction(options.protyle, [{
|
||||
action: "hideAttrViewName",
|
||||
avID,
|
||||
blockID,
|
||||
data: false
|
||||
}], [{
|
||||
action: "hideAttrViewName",
|
||||
avID,
|
||||
blockID,
|
||||
data: true
|
||||
data: checked
|
||||
}]);
|
||||
if (checked) {
|
||||
options.blockElement.querySelector(".av__title").classList.remove("fn__none");
|
||||
} else {
|
||||
// hide
|
||||
options.blockElement.querySelector(".av__title").classList.add("fn__none");
|
||||
}
|
||||
if (options.data.viewType === "gallery") {
|
||||
const galleryElement = options.blockElement.querySelector(".av__gallery");
|
||||
if (checked) {
|
||||
galleryElement.classList.remove("av__gallery--top");
|
||||
} else {
|
||||
// hide
|
||||
galleryElement.classList.add("av__gallery--top");
|
||||
}
|
||||
}
|
||||
});
|
||||
if (options.data.viewType !== "gallery") {
|
||||
return;
|
||||
}
|
||||
const toggleFitElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-gallery-fit"]') as HTMLInputElement;
|
||||
toggleFitElement.addEventListener("change", () => {
|
||||
const avID = options.blockElement.getAttribute("data-av-id");
|
||||
const blockID = options.blockElement.getAttribute("data-node-id");
|
||||
const checked = toggleFitElement.checked;
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewFitImage",
|
||||
avID,
|
||||
blockID,
|
||||
data: checked
|
||||
}], [{
|
||||
action: "setAttrViewFitImage",
|
||||
avID,
|
||||
blockID,
|
||||
data: !checked
|
||||
}]);
|
||||
options.blockElement.querySelectorAll(".av__gallery-img").forEach(item => {
|
||||
if (checked) {
|
||||
item.classList.add("av__gallery-img--fit");
|
||||
} else {
|
||||
item.classList.remove("av__gallery-img--fit");
|
||||
}
|
||||
})
|
||||
});
|
||||
const toggleIconElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-gallery-icon"]') as HTMLInputElement;
|
||||
toggleIconElement.addEventListener("change", () => {
|
||||
const avID = options.blockElement.getAttribute("data-av-id");
|
||||
const blockID = options.blockElement.getAttribute("data-node-id");
|
||||
const checked = toggleIconElement.checked;
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewShowIcon",
|
||||
avID,
|
||||
blockID,
|
||||
data: checked
|
||||
}], [{
|
||||
action: "setAttrViewShowIcon",
|
||||
avID,
|
||||
blockID,
|
||||
data: !checked
|
||||
}]);
|
||||
});
|
||||
const toggleWrapElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-gallery-wrap"]') as HTMLInputElement;
|
||||
toggleWrapElement.addEventListener("change", () => {
|
||||
const avID = options.blockElement.getAttribute("data-av-id");
|
||||
const blockID = options.blockElement.getAttribute("data-node-id");
|
||||
const checked = toggleWrapElement.checked;
|
||||
transaction(options.protyle, [{
|
||||
action: "setAttrViewWrapField",
|
||||
avID,
|
||||
blockID,
|
||||
data: checked
|
||||
}], [{
|
||||
action: "setAttrViewWrapField",
|
||||
avID,
|
||||
blockID,
|
||||
data: !checked
|
||||
}]);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import {openCalcMenu} from "./calc";
|
|||
import {escapeAttr, escapeHtml} from "../../../util/escape";
|
||||
import {Dialog} from "../../../dialog";
|
||||
import {bindLayoutEvent, getLayoutHTML} from "./layout";
|
||||
import {setGalleryCover, setGallerySize} from "./gallery/util";
|
||||
|
||||
export const openMenuPanel = (options: {
|
||||
protyle: IProtyle,
|
||||
|
|
@ -1360,6 +1361,36 @@ export const openMenuPanel = (options: {
|
|||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
} else if (type === "set-gallery-cover") {
|
||||
setGalleryCover({
|
||||
target,
|
||||
protyle: options.protyle,
|
||||
nodeElement: options.blockElement,
|
||||
view: data.view as IAVGallery
|
||||
});
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
} else if (type === "set-gallery-size") {
|
||||
setGallerySize({
|
||||
target,
|
||||
protyle: options.protyle,
|
||||
nodeElement: options.blockElement,
|
||||
view: data.view as IAVGallery
|
||||
});
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
} else if (type === "set-layout") {
|
||||
setPageSize({
|
||||
target,
|
||||
protyle: options.protyle,
|
||||
avID,
|
||||
nodeElement: options.blockElement
|
||||
});
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
}
|
||||
// 有错误日志,没找到重现步骤,需先判断一下
|
||||
if (!target || !target.parentElement) {
|
||||
|
|
|
|||
|
|
@ -850,7 +850,8 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
|
|||
"replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColPin", "addAttrViewView", "setAttrViewColIcon",
|
||||
"removeAttrViewView", "setAttrViewViewName", "setAttrViewViewIcon", "duplicateAttrViewView", "sortAttrViewView",
|
||||
"updateAttrViewColRelation", "setAttrViewPageSize", "updateAttrViewColRollup", "sortAttrViewKey",
|
||||
"duplicateAttrViewKey", "setAttrViewViewDesc", "setAttrViewColDesc"].includes(operation.action)) {
|
||||
"duplicateAttrViewKey", "setAttrViewViewDesc", "setAttrViewColDesc", "setAttrViewCoverFrom", "setAttrViewShowIcon",
|
||||
"setAttrViewCoverFromAssetKeyID", "changeAttrViewLayout"].includes(operation.action)) {
|
||||
if (!isUndo) {
|
||||
// 撤销 transaction 会进行推送,需使用推送来进行刷新最新数据 https://github.com/siyuan-note/siyuan/issues/13607
|
||||
refreshAV(protyle, operation);
|
||||
|
|
|
|||
8
app/src/types/index.d.ts
vendored
8
app/src/types/index.d.ts
vendored
|
|
@ -51,6 +51,13 @@ type TOperation =
|
|||
| "moveOutlineHeading"
|
||||
| "updateAttrViewColRollup"
|
||||
| "hideAttrViewName"
|
||||
| "setAttrViewCardSize"
|
||||
| "setAttrViewCoverFrom"
|
||||
| "setAttrViewCoverFromAssetKeyID"
|
||||
| "setAttrViewFitImage"
|
||||
| "setAttrViewShowIcon"
|
||||
| "setAttrViewWrapField"
|
||||
| "changeAttrViewLayout"
|
||||
| "setAttrViewColDate"
|
||||
| "unbindAttrViewBlock"
|
||||
| "setAttrViewViewDesc"
|
||||
|
|
@ -840,6 +847,7 @@ interface IAVTable extends IAVView {
|
|||
|
||||
interface IAVGallery extends IAVView {
|
||||
coverFrom: number; // 0:无,1:内容图,2:资源字段
|
||||
coverFromAssetKeyID?: string;
|
||||
cardSize: number; // 0:小卡片,1:中卡片,2:大卡片
|
||||
fitImage: boolean;
|
||||
showIcon: boolean;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue