A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {transaction} from "../../wysiwyg/transaction";
2import {Constants} from "../../../constants";
3import {fetchSyncPost} from "../../../util/fetch";
4import {getCardAspectRatio} from "./gallery/util";
5import {getFieldsByData} from "./view";
6
7export const getLayoutHTML = (data: IAV) => {
8 let html = "";
9 const view = data.view as IAVGallery;
10 if (data.viewType === "gallery") {
11 let coverFromTitle = "";
12 if (view.coverFrom === 0) {
13 coverFromTitle = window.siyuan.languages.calcOperatorNone;
14 } else if (view.coverFrom === 1) {
15 coverFromTitle = window.siyuan.languages.contentImage;
16 } else if (view.coverFrom === 3) {
17 coverFromTitle = window.siyuan.languages.contentBlock;
18 } else {
19 view.fields.find(item => {
20 if (item.type === "mAsset" && item.id === view.coverFromAssetKeyID) {
21 coverFromTitle = item.name;
22 return true;
23 }
24 });
25 }
26 html = `<button class="b3-menu__item" data-type="set-gallery-cover">
27 <span class="fn__flex-center">${window.siyuan.languages.cardPreview1}</span>
28 <span class="fn__flex-1"></span>
29 <span class="b3-menu__accelerator">${coverFromTitle}</span>
30 <svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
31</button>
32<button class="b3-menu__item" data-type="set-gallery-ratio">
33 <span class="fn__flex-center">${window.siyuan.languages.cardAspectRatio}</span>
34 <span class="fn__flex-1"></span>
35 <span class="b3-menu__accelerator">${getCardAspectRatio(view.cardAspectRatio)}</span>
36 <svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
37</button>
38<button class="b3-menu__item" data-type="set-gallery-size">
39 <span class="fn__flex-center">${window.siyuan.languages.cardSize}</span>
40 <span class="fn__flex-1"></span>
41 <span class="b3-menu__accelerator">${view.cardSize === 0 ? window.siyuan.languages.small : (view.cardSize === 1 ? window.siyuan.languages.medium : window.siyuan.languages.large)}</span>
42 <svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
43</button>
44<label class="b3-menu__item">
45 <span class="fn__flex-center">${window.siyuan.languages.fitImage}</span>
46 <span class="fn__space fn__flex-1"></span>
47 <input data-type="toggle-gallery-fit" type="checkbox" class="b3-switch b3-switch--menu" ${view.fitImage ? "checked" : ""}>
48</label>
49<label class="b3-menu__item">
50 <span class="fn__flex-center">${window.siyuan.languages.displayFieldName}</span>
51 <span class="fn__space fn__flex-1"></span>
52 <input data-type="toggle-gallery-name" type="checkbox" class="b3-switch b3-switch--menu" ${view.displayFieldName ? "checked" : ""}>
53</label>`;
54 }
55 return `<div class="b3-menu__items">
56 <div class="b3-menu__items">
57 <button class="b3-menu__item" data-type="nobg">
58 <span class="block__icon" style="padding: 8px;margin-left: -4px;" data-type="go-config">
59 <svg><use xlink:href="#iconLeft"></use></svg>
60 </span>
61 <span class="b3-menu__label ft__center">${window.siyuan.languages.layout}</span>
62 </button>
63 <button class="b3-menu__separator"></button>
64 <button class="b3-menu__item" data-type="nobg">
65 <div class="av__layout">
66 <div data-type="set-layout" data-view-type="table" class="av__layout-item${data.viewType === "table" ? " av__layout-item--select" : ""}">
67 <svg><use xlink:href="#iconTable"></use></svg>
68 <div class="fn__hr"></div>
69 <div>${window.siyuan.languages.table}</div>
70 </div>
71 <div data-type="set-layout" data-view-type="gallery" class="av__layout-item${data.viewType === "gallery" ? " av__layout-item--select" : ""}">
72 <svg><use xlink:href="#iconGallery"></use></svg>
73 <div class="fn__hr"></div>
74 <div>${window.siyuan.languages.gallery}</div>
75 </div>
76 </div>
77 </button>
78 <label class="b3-menu__item">
79 <span class="fn__flex-center">${window.siyuan.languages.showTitle}</span>
80 <span class="fn__space fn__flex-1"></span>
81 <input data-type="toggle-view-title" type="checkbox" class="b3-switch b3-switch--menu" ${view.hideAttrViewName ? "" : "checked"}>
82 </label>
83 ${html}
84 <label class="b3-menu__item">
85 <span class="fn__flex-center">${window.siyuan.languages.showAllEntriesIcons}</span>
86 <span class="fn__space fn__flex-1"></span>
87 <input data-type="toggle-entries-icons" type="checkbox" class="b3-switch b3-switch--menu" ${view.showIcon ? "checked" : ""}>
88 </label>
89 <label class="b3-menu__item">
90 <span class="fn__flex-center">${window.siyuan.languages.wrapAllFields}</span>
91 <span class="fn__space fn__flex-1"></span>
92 <input data-type="toggle-entries-wrap" type="checkbox" class="b3-switch b3-switch--menu" ${view.wrapField ? "checked" : ""}>
93 </label>
94 <button class="b3-menu__item" data-type="set-page-size" data-size="${view.pageSize}">
95 <span class="fn__flex-center">${window.siyuan.languages.entryNum}</span>
96 <span class="fn__flex-1"></span>
97 <span class="b3-menu__accelerator">${view.pageSize === Constants.SIZE_DATABASE_MAZ_SIZE ? window.siyuan.languages.all : view.pageSize}</span>
98 <svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
99 </button>
100</div>`;
101};
102
103export const bindLayoutEvent = (options: {
104 protyle: IProtyle,
105 data: IAV,
106 menuElement: HTMLElement
107 blockElement: Element
108}) => {
109 const toggleTitleElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-view-title"]') as HTMLInputElement;
110 toggleTitleElement.addEventListener("change", () => {
111 const avID = options.blockElement.getAttribute("data-av-id");
112 const blockID = options.blockElement.getAttribute("data-node-id");
113 const checked = toggleTitleElement.checked;
114 transaction(options.protyle, [{
115 action: "hideAttrViewName",
116 avID,
117 blockID,
118 data: !checked
119 }], [{
120 action: "hideAttrViewName",
121 avID,
122 blockID,
123 data: checked
124 }]);
125 options.data.view.hideAttrViewName = !checked;
126 });
127 const toggleIconElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-entries-icons"]') as HTMLInputElement;
128 toggleIconElement.addEventListener("change", () => {
129 const avID = options.blockElement.getAttribute("data-av-id");
130 const blockID = options.blockElement.getAttribute("data-node-id");
131 const checked = toggleIconElement.checked;
132 transaction(options.protyle, [{
133 action: "setAttrViewShowIcon",
134 avID,
135 blockID,
136 data: checked
137 }], [{
138 action: "setAttrViewShowIcon",
139 avID,
140 blockID,
141 data: !checked
142 }]);
143 options.data.view.showIcon = checked;
144 });
145 const toggleWrapElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-entries-wrap"]') as HTMLInputElement;
146 toggleWrapElement.addEventListener("change", () => {
147 const avID = options.blockElement.getAttribute("data-av-id");
148 const blockID = options.blockElement.getAttribute("data-node-id");
149 const checked = toggleWrapElement.checked;
150 transaction(options.protyle, [{
151 action: "setAttrViewWrapField",
152 avID,
153 blockID,
154 data: checked
155 }], [{
156 action: "setAttrViewWrapField",
157 avID,
158 blockID,
159 data: !checked
160 }]);
161 getFieldsByData(options.data).forEach(item => {
162 item.wrap = checked;
163 });
164 options.data.view.wrapField = checked;
165 });
166 if (options.data.viewType !== "gallery") {
167 return;
168 }
169 const toggleFitElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-gallery-fit"]') as HTMLInputElement;
170 toggleFitElement.addEventListener("change", () => {
171 const avID = options.blockElement.getAttribute("data-av-id");
172 const blockID = options.blockElement.getAttribute("data-node-id");
173 const checked = toggleFitElement.checked;
174 transaction(options.protyle, [{
175 action: "setAttrViewFitImage",
176 avID,
177 blockID,
178 data: checked
179 }], [{
180 action: "setAttrViewFitImage",
181 avID,
182 blockID,
183 data: !checked
184 }]);
185 (options.data.view as IAVGallery).fitImage = checked;
186 });
187 const toggleNameElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-gallery-name"]') as HTMLInputElement;
188 toggleNameElement.addEventListener("change", () => {
189 const avID = options.blockElement.getAttribute("data-av-id");
190 const blockID = options.blockElement.getAttribute("data-node-id");
191 const checked = toggleNameElement.checked;
192 transaction(options.protyle, [{
193 action: "setAttrViewDisplayFieldName",
194 avID,
195 blockID,
196 data: checked
197 }], [{
198 action: "setAttrViewDisplayFieldName",
199 avID,
200 blockID,
201 data: !checked
202 }]);
203 (options.data.view as IAVGallery).displayFieldName = checked;
204 });
205};
206
207export const updateLayout = async (options: {
208 data: IAV
209 nodeElement: Element,
210 protyle: IProtyle,
211 target: HTMLElement
212}) => {
213 if (options.target.classList.contains("av__layout-item--select") || options.target.dataset.load === "true") {
214 return;
215 }
216 options.target.dataset.load = "true";
217 options.target.parentElement.querySelector(".av__layout-item--select").classList.remove("av__layout-item--select");
218 options.target.classList.add("av__layout-item--select");
219 const response = await fetchSyncPost("/api/av/changeAttrViewLayout", {
220 blockID: options.nodeElement.getAttribute("data-node-id"),
221 avID: options.nodeElement.getAttribute("data-av-id"),
222 layoutType: options.target.getAttribute("data-view-type")
223 });
224 const menuElement = document.querySelector(".av__panel").lastElementChild as HTMLElement;
225 menuElement.innerHTML = getLayoutHTML(response.data);
226 bindLayoutEvent({
227 protyle: options.protyle,
228 data: response.data,
229 menuElement,
230 blockElement: options.nodeElement
231 });
232 options.target.removeAttribute("data-load");
233 return response.data;
234};