mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-09-24 13:37:31 +08:00
Enable sliding categories and extract TODOs
This commit is contained in:
parent
e7a3f6d17e
commit
5391521c08
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>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user