mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Enable sliding categories and extract TODOs
This commit is contained in:
		
							
								
								
									
										29
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | # TODOs | ||||||
|  |  | ||||||
|  | This doc contains a list of TODOs taken from the code and organized. This _does not_ includes things like upcoming features or fixes. | ||||||
|  |  | ||||||
|  | ## Scripts | ||||||
|  |  | ||||||
|  | - Create a logger | ||||||
|  | - Modify esbuild to allow for a development build to contain debug logs | ||||||
|  | - Modify custom highlight.js plugin to include highlighting for jQuery global functions | ||||||
|  | - Either move highlight.js inclusion to template or use a mapping of note IDs to files | ||||||
|  | - Adjust search to use separate function (clean code) | ||||||
|  | - Consider never removing the search results from the page and update container instead | ||||||
|  | - Consolidate theme initialization (DRY) | ||||||
|  |  | ||||||
|  | ## Styles | ||||||
|  |  | ||||||
|  | -  | ||||||
|  |  | ||||||
|  | ## Templates | ||||||
|  |  | ||||||
|  | - Consider adding highlight.js into the templates instead of scripts | ||||||
|  | - Find a better way to integrate ts/js to templates (maybe via includes?) | ||||||
|  |  | ||||||
|  | ## Other | ||||||
|  |  | ||||||
|  | - Create a logical set of attributes for setting open-graph/twitter metadata | ||||||
|  | - Consider making book type notes explicitly required for full-link category | ||||||
|  |     - This lets text type notes still have content but require clicking arrow to expand | ||||||
|  | - Find a way to better map template to notes and allow for automatically creating new ones | ||||||
| @@ -1,30 +1,11 @@ | |||||||
| // import fixActiveLink from "./fixes/activelink"; |  | ||||||
| // import fixTableHeaders from "./fixes/tableheaders"; |  | ||||||
| import highlight from "./modules/highlight"; | import highlight from "./modules/highlight"; | ||||||
| // import buildSidenav from "./navigation/sidenav"; |  | ||||||
| // import buildBreadcrumbs from "./navigation/breadcrumbs"; |  | ||||||
| // import fixSubMenus from "./fixes/submenu"; |  | ||||||
| import setupToC from "./modules/toc"; | import setupToC from "./modules/toc"; | ||||||
| // import addExternalLinks from "./fixes/externallinks"; |  | ||||||
| // import injectSwagger from "./other/swagger"; |  | ||||||
| // import makeMobileMenu from "./other/mobile"; |  | ||||||
| import setupExpanders from "./modules/expanders"; | import setupExpanders from "./modules/expanders"; | ||||||
| import setupMobileMenu from "./modules/mobile"; | import setupMobileMenu from "./modules/mobile"; | ||||||
| import setupSearch from "./modules/search"; | import setupSearch from "./modules/search"; | ||||||
| import setupThemeSelector from "./modules/theme"; | import setupThemeSelector from "./modules/theme"; | ||||||
|  |  | ||||||
|  |  | ||||||
| // const ETAPI_REF_NOTE_ID = "pPIXi0uwF5GX"; |  | ||||||
| // const HIDDEN_SUBMENUS = ["blog"]; |  | ||||||
| // const EXTERNAL_LINKS = { |  | ||||||
| //     EGFtX8Uw96FQ: "https://github.com/zadam/trilium", |  | ||||||
| //     dXAKFE0fJtom: "https://discord.gg/eTaTXUgcBr" |  | ||||||
| // }; |  | ||||||
| // const ALIASES = { |  | ||||||
| //     WqBnya4Ye8rS: "", |  | ||||||
| //     ZapIU17QNEyU: "blog" |  | ||||||
| // }; |  | ||||||
|  |  | ||||||
| function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Parameters<T>) { | function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Parameters<T>) { | ||||||
|     try { |     try { | ||||||
|         func.apply(func, args); |         func.apply(func, args); | ||||||
| @@ -33,51 +14,9 @@ function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Paramete | |||||||
|         console.error(e); // eslint-disable-line no-console |         console.error(e); // eslint-disable-line no-console | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Lots of these functions seem to depend on each other indirectly |  | ||||||
|  * through DOM changes or classes or what-have-you. This is |  | ||||||
|  * obviously not ideal as it makes things less clear, and also |  | ||||||
|  * makes TypeScript less helpful. |  | ||||||
|  *  |  | ||||||
|  * TODO: Find a good way of restructuring that allows things |  | ||||||
|  * to act a bit more harmoniously. |  | ||||||
|  *  |  | ||||||
|  * TODO: Make use of esbuild's define api to enable a debug |  | ||||||
|  * build that contains all the console logs and such. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| // Perform fixes first |  | ||||||
| // $try(fixActiveLink, ALIASES); |  | ||||||
| // $try(fixTableHeaders); |  | ||||||
| // $try(fixSubMenus, HIDDEN_SUBMENUS); |  | ||||||
| // $try(addExternalLinks, EXTERNAL_LINKS); |  | ||||||
|  |  | ||||||
| // Now layout changes |  | ||||||
| // $try(buildBreadcrumbs); |  | ||||||
| // $try(buildSidenav); |  | ||||||
|  |  | ||||||
| $try(setupToC); | $try(setupToC); | ||||||
|  |  | ||||||
| // Finally, other features |  | ||||||
| // TODO: how difficult this would be to implement via |  | ||||||
| // templates or trilium |  | ||||||
| $try(highlight); | $try(highlight); | ||||||
| // $try(injectSwagger, ETAPI_REF_NOTE_ID); |  | ||||||
|  |  | ||||||
| // "Standard" Modules I would recommend the new share |  | ||||||
| // theme have |  | ||||||
| $try(setupExpanders); | $try(setupExpanders); | ||||||
| $try(setupMobileMenu); | $try(setupMobileMenu); | ||||||
| $try(setupSearch); | $try(setupSearch); | ||||||
| $try(setupThemeSelector); | $try(setupThemeSelector); | ||||||
| // $try(makeMobileMenu); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * This no longer uses a traefik plugin and instead a custom |  | ||||||
|  * template being served through Trilium. |  | ||||||
|  *  |  | ||||||
|  * TODO: Figure out some good attributes to use to populate |  | ||||||
|  * this inside the template to make it more dynamic |  | ||||||
|  */ |  | ||||||
| // $try(addOpenGraphMeta); |  | ||||||
|   | |||||||
| @@ -1,30 +1,3 @@ | |||||||
| // function anchorToId(anchor: HTMLAnchorElement) { |  | ||||||
| //     return anchor.href.replace("./", ""); |  | ||||||
| // } |  | ||||||
| //  |  | ||||||
| // const stored = localStorage.getItem("expanded") ?? "[]"; |  | ||||||
| // let parsed: string[]; |  | ||||||
| // try { |  | ||||||
| //     parsed = JSON.parse(stored) as string[]; |  | ||||||
| // } |  | ||||||
| // catch (e) { |  | ||||||
| //     parsed = []; |  | ||||||
| // } |  | ||||||
| // const state = new Set(parsed); |  | ||||||
| // const submenus = Array.from(document.querySelectorAll("#menu .submenu-item")); |  | ||||||
| // for (const sub of submenus) { |  | ||||||
| //     try { |  | ||||||
| //         if (state.has(anchorToId(sub.children[0] as HTMLAnchorElement))) sub.classList.add("expanded"); |  | ||||||
| //     } |  | ||||||
| //     catch (e) { |  | ||||||
| //         // TODO: create logger |  | ||||||
| //         console.warn("Could not restore expanded state"); // eslint-disable-line no-console |  | ||||||
| //         console.error(e); // eslint-disable-line no-console |  | ||||||
| //     } |  | ||||||
| // } |  | ||||||
|  |  | ||||||
| // TODO: Swap this system to use type-book for full-link category |  | ||||||
|  |  | ||||||
| // In case a linked article lead to a new tree | // In case a linked article lead to a new tree | ||||||
| const activeLink = document.querySelector("#menu a.active"); | const activeLink = document.querySelector("#menu a.active"); | ||||||
| if (activeLink) { | if (activeLink) { | ||||||
| @@ -45,15 +18,10 @@ export default function setupExpanders() { | |||||||
|             if ((e.target as Element).closest(".submenu-item,.item") !== ex) return; |             if ((e.target as Element).closest(".submenu-item,.item") !== ex) return; | ||||||
|             e.preventDefault(); |             e.preventDefault(); | ||||||
|             e.stopPropagation(); |             e.stopPropagation(); | ||||||
|             // ex.parentElement.parentElement.classList.toggle("expanded"); |             const ul = ex.querySelector("ul")!; | ||||||
|             ex.classList.toggle("expanded"); |             ul.style.height = `${ul.scrollHeight}px`; | ||||||
|             // const id = anchorToId(ex.closest("a")!); |             setTimeout(() => ex.classList.toggle("expanded"), 1); | ||||||
|             // if (state.has(id)) state.delete(id); |             setTimeout(() => ul.style.height = ``, 200); | ||||||
|             // else state.add(id); |  | ||||||
|             // // TODO: be able to remove all submenus of currently collapsed |  | ||||||
|             // localStorage.setItem("expanded", JSON.stringify([...state])); |  | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -19,7 +19,6 @@ const highlightJQuery: HLJSPlugin = { | |||||||
|         result.value = result.value.replaceAll(/([^A-Za-z0-9.])\$\((.+)\)/g, function(match, prefix, variable) { |         result.value = result.value.replaceAll(/([^A-Za-z0-9.])\$\((.+)\)/g, function(match, prefix, variable) { | ||||||
|             return `${prefix}<span class="hljs-variable language_">$(</span>${variable}<span class="hljs-variable language_">)</span>`; |             return `${prefix}<span class="hljs-variable language_">$(</span>${variable}<span class="hljs-variable language_">)</span>`; | ||||||
|         }); |         }); | ||||||
|         // TODO: add highlighting for static calls like $.ajax |  | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -32,14 +31,12 @@ export default function addHljs() { | |||||||
|     if (!codeblocks.length) return; // If there are none, don't add dependency |     if (!codeblocks.length) return; // If there are none, don't add dependency | ||||||
|  |  | ||||||
|     // Add the hightlight.js styles from the child note of this script |     // Add the hightlight.js styles from the child note of this script | ||||||
|     // TODO: make this a mapping |  | ||||||
|     const link = document.createElement("link"); |     const link = document.createElement("link"); | ||||||
|     link.rel = "stylesheet"; |     link.rel = "stylesheet"; | ||||||
|     link.href = "api/notes/cVaK9ZJwx5Hs/download"; |     link.href = "api/notes/cVaK9ZJwx5Hs/download"; | ||||||
|     document.head.append(link); |     document.head.append(link); | ||||||
|  |  | ||||||
|     // Add the highlight.js script too |     // Add the highlight.js script too | ||||||
|     // TODO: make this a mappin as well |  | ||||||
|     const script = document.createElement("script"); |     const script = document.createElement("script"); | ||||||
|     script.src = "api/notes/6PVElIem02b5/download"; |     script.src = "api/notes/6PVElIem02b5/download"; | ||||||
|     script.addEventListener("load", () => { |     script.addEventListener("load", () => { | ||||||
|   | |||||||
| @@ -25,7 +25,6 @@ function buildResultItem(result: SearchResult) { | |||||||
| export default function setupSearch() { | export default function setupSearch() { | ||||||
|     const searchInput: HTMLInputElement = document.querySelector(".search-input")!; |     const searchInput: HTMLInputElement = document.querySelector(".search-input")!; | ||||||
|  |  | ||||||
|     // TODO: move listener to another function |  | ||||||
|     searchInput.addEventListener("keyup", debounce(async () => { |     searchInput.addEventListener("keyup", debounce(async () => { | ||||||
|         // console.log("CHANGE EVENT"); |         // console.log("CHANGE EVENT"); | ||||||
|         const current = document.body.dataset.noteId; |         const current = document.body.dataset.noteId; | ||||||
| @@ -48,7 +47,7 @@ export default function setupSearch() { | |||||||
|         container.style.minWidth = `${rect.width}px`; |         container.style.minWidth = `${rect.width}px`; | ||||||
|          |          | ||||||
|         const existing = document.querySelector(".search-results"); |         const existing = document.querySelector(".search-results"); | ||||||
|         if (existing) existing.replaceWith(container); // TODO: consider updating existing container and never removing |         if (existing) existing.replaceWith(container); | ||||||
|         else document.body.append(container); |         else document.body.append(container); | ||||||
|     }, 500)); |     }, 500)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,6 @@ if (preference) { | |||||||
|  |  | ||||||
| export default function setupThemeSelector() { | export default function setupThemeSelector() { | ||||||
|     const themeSwitch: HTMLInputElement = document.querySelector(".theme-selection input")!; |     const themeSwitch: HTMLInputElement = document.querySelector(".theme-selection input")!; | ||||||
|     // TODO: consolidate this with initialization (DRY) |  | ||||||
|     themeSwitch?.addEventListener("change", () => { |     themeSwitch?.addEventListener("change", () => { | ||||||
|         if (themeSwitch.checked) { |         if (themeSwitch.checked) { | ||||||
|             document.body.classList.add("theme-dark"); |             document.body.classList.add("theme-dark"); | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -50,7 +50,7 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| #menu li > ul { | #menu li > ul { | ||||||
|     transition: height 1000ms ease; |     transition: height 200ms ease; | ||||||
| } | } | ||||||
|  |  | ||||||
| #menu li:not(.expanded) > ul { | #menu li:not(.expanded) > ul { | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ const customServerYml = `- url: "{protocol}://{domain}:{port}/etapi" | |||||||
|     <% } %> |     <% } %> | ||||||
|     <%- header %> |     <%- header %> | ||||||
|     <title><%= note.title %><% if (note.noteId !== subRoot.noteId) { %> - <%= subRoot.title %><% } %></title> |     <title><%= note.title %><% if (note.noteId !== subRoot.noteId) { %> - <%= subRoot.title %><% } %></title> | ||||||
|     <!-- TODO: determine a good way to populate this via labels --> |  | ||||||
|     <!-- HTML Meta Tags --> |     <!-- HTML Meta Tags --> | ||||||
|     <meta name="description" content="A website for guides, reference, showcase, inspiration, and more, all for Trilium Notes! Not convinced? Come see for yourself just what Trilium can do." |     <meta name="description" content="A website for guides, reference, showcase, inspiration, and more, all for Trilium Notes! Not convinced? Come see for yourself just what Trilium can do." | ||||||
|     ><!-- Facebook Meta Tags --> |     ><!-- Facebook Meta Tags --> | ||||||
| @@ -97,9 +97,9 @@ content = content.replaceAll(headingRe, (...match) => { | |||||||
| %> | %> | ||||||
| <body data-note-id="<%= note.noteId %>" class="type-<%= note.type %><%= themeClass %>"> | <body data-note-id="<%= note.noteId %>" class="type-<%= note.type %><%= themeClass %>"> | ||||||
| <div id="mobile-header"> | <div id="mobile-header"> | ||||||
|     <a href="./<%= subRoot.shareId %>"> |     <a href="./"> | ||||||
|         <% if (subRoot.hasRelation("shareLogo")) { %> |         <% if (subRoot.hasRelation("shareLogo")) { %> | ||||||
|             <img src="api/notes/<%= subRoot.getRelation("shareLogo").value %>/download" alt="Logo" /> |             <img src="api/images/<%= subRoot.getRelation("shareLogo").value %>/logo.svg" alt="Logo" /> | ||||||
|         <% } %> |         <% } %> | ||||||
|         <%= subRoot.title %> |         <%= subRoot.title %> | ||||||
|     </a> |     </a> | ||||||
| @@ -109,9 +109,9 @@ content = content.replaceAll(headingRe, (...match) => { | |||||||
|     <div id="left-pane"> |     <div id="left-pane"> | ||||||
|         <div id="navigation"> |         <div id="navigation"> | ||||||
|             <div id="site-header"> |             <div id="site-header"> | ||||||
|                 <a href="./<%= subRoot.shareId %>"> |                 <a href="./"> | ||||||
|                     <% if (subRoot.hasRelation("shareLogo")) { %> |                     <% if (subRoot.hasRelation("shareLogo")) { %> | ||||||
|                         <img src="api/notes/<%= subRoot.getRelation("shareLogo").value %>/download" alt="Logo" /> |                         <img src="api/images/<%= subRoot.getRelation("shareLogo").value %>/logo.svg" alt="Logo" /> | ||||||
|                     <% } %> |                     <% } %> | ||||||
|                     <%= subRoot.title %> |                     <%= subRoot.title %> | ||||||
|                 </a> |                 </a> | ||||||
| @@ -198,12 +198,8 @@ content = content.replaceAll(headingRe, (...match) => { | |||||||
|             <div id="toc-pane"> |             <div id="toc-pane"> | ||||||
|                 <h3>On This Page</h3> |                 <h3>On This Page</h3> | ||||||
|                 <ul id="toc"> |                 <ul id="toc"> | ||||||
|                     <% |                     <% for (const entry of toc) { %> | ||||||
|                     let active = true; |                         <%- include('toc_item', {entry}) %> | ||||||
|                     for (const entry of toc) { |  | ||||||
|                     %> |  | ||||||
|                         <%- include('toc_item', {entry, active}) %> |  | ||||||
|                         <% active = false %> |  | ||||||
|                     <% } %> |                     <% } %> | ||||||
|                 </ul> |                 </ul> | ||||||
|             </div> |             </div> | ||||||
|   | |||||||
| @@ -5,14 +5,14 @@ const slug = slugify(entry.name); | |||||||
|  |  | ||||||
|  |  | ||||||
| <li> | <li> | ||||||
|     <a href="#<%= slug %>"<% if (active) { %> class="active"<% } %>> |     <a href="#<%= slug %>"> | ||||||
|         <%= entry.name %> |         <%= entry.name %> | ||||||
|     </a> |     </a> | ||||||
|  |  | ||||||
|     <% if (entry.children.length) { %> |     <% if (entry.children.length) { %> | ||||||
|         <ul> |         <ul> | ||||||
|             <% for (const subentry of entry.children) { %> |             <% for (const subentry of entry.children) { %> | ||||||
|                 <%- include('toc_item', {entry: subentry, active: false}) %> |                 <%- include('toc_item', {entry: subentry}) %> | ||||||
|             <% } %> |             <% } %> | ||||||
|         </ul> |         </ul> | ||||||
|     <% } %> |     <% } %> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user