A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 234 lines 11 kB view raw
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};