Merge branch 'develop' into note-create

This commit is contained in:
SiriusXT 2025-06-18 11:21:32 +08:00
commit 5fc0a0460d
117 changed files with 2646 additions and 1822 deletions

6
.gitignore vendored
View File

@ -1,11 +1,5 @@
# See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
# Workaround for Nx bug: parent .gitignore files with '*' can cause
# `nx show projects` to return nothing by ignoring subprojects.
# See: https://github.com/nrwl/nx/issues/27368
# Unignore everything to ensure Nx detects all projects
!*
# compiled output
dist
tmp

View File

@ -1 +1,6 @@
VITE_CKEDITOR_ENABLE_INSPECTOR=false
# The development license key for premium CKEditor features.
# Note: This key must only be used for the Trilium Notes project.
# Expires on: 2025-09-13
VITE_CKEDITOR_KEY=eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3NTc3MjE1OTksImp0aSI6ImFiN2E0NjZmLWJlZGMtNDNiYy1iMzU4LTk0NGQ0YWJhY2I3ZiIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOlsic2giLCJkcnVwYWwiXSwid2hpdGVMYWJlbCI6dHJ1ZSwiZmVhdHVyZXMiOlsiRFJVUCIsIkNNVCIsIkRPIiwiRlAiLCJTQyIsIlRPQyIsIlRQTCIsIlBPRSIsIkNDIiwiTUYiLCJTRUUiLCJFQ0giLCJFSVMiXSwidmMiOiI1MzlkOWY5YyJ9.2rvKPql4hmukyXhEtWPZ8MLxKvzPIwzCdykO653g7IxRRZy2QJpeRszElZx9DakKYZKXekVRAwQKgHxwkgbE_w

View File

@ -281,6 +281,7 @@ export type CommandMappings = {
buildIcon(name: string): NativeImage;
};
refreshTouchBar: CommandData;
reloadTextEditor: CommandData;
};
type EventMappings = {

View File

@ -245,6 +245,10 @@ class FrocaImpl implements Froca {
}
async getNotes(noteIds: string[] | JQuery<string>, silentNotFoundError = false): Promise<FNote[]> {
if (noteIds.length === 0) {
return [];
}
noteIds = Array.from(new Set(noteIds)); // make unique
const missingNoteIds = noteIds.filter((noteId) => !this.notes[noteId]);

View File

@ -4,6 +4,8 @@ import { t } from "./i18n.js";
import type { MenuItem } from "../menus/context_menu.js";
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
const SEPARATOR = { title: "----" };
async function getNoteTypeItems(command?: TreeCommandNames) {
const items: MenuItem<TreeCommandNames>[] = [
{ title: t("note_types.text"), command, type: "text", uiIcon: "bx bx-note" },
@ -18,14 +20,23 @@ async function getNoteTypeItems(command?: TreeCommandNames) {
{ title: t("note_types.web-view"), command, type: "webView", uiIcon: "bx bx-globe-alt" },
{ title: t("note_types.mind-map"), command, type: "mindMap", uiIcon: "bx bx-sitemap" },
{ title: t("note_types.geo-map"), command, type: "geoMap", uiIcon: "bx bx-map-alt" },
...await getBuiltInTemplates(command),
...await getUserTemplates(command)
];
return items;
}
async function getUserTemplates(command?: TreeCommandNames) {
const templateNoteIds = await server.get<string[]>("search-templates");
const templateNotes = await froca.getNotes(templateNoteIds);
if (templateNotes.length === 0) {
return [];
}
if (templateNotes.length > 0) {
items.push({ title: "----" });
const items: MenuItem<TreeCommandNames>[] = [
SEPARATOR
];
for (const templateNote of templateNotes) {
items.push({
title: templateNote.title,
@ -35,8 +46,33 @@ async function getNoteTypeItems(command?: TreeCommandNames) {
templateNoteId: templateNote.noteId
});
}
return items;
}
async function getBuiltInTemplates(command?: TreeCommandNames) {
const templatesRoot = await froca.getNote("_templates");
if (!templatesRoot) {
console.warn("Unable to find template root.");
return [];
}
const childNotes = await templatesRoot.getChildNotes();
if (childNotes.length === 0) {
return [];
}
const items: MenuItem<TreeCommandNames>[] = [
SEPARATOR
];
for (const templateNote of childNotes) {
items.push({
title: templateNote.title,
uiIcon: templateNote.getIcon(),
command: command,
type: templateNote.type,
templateNoteId: templateNote.noteId
});
}
return items;
}

View File

@ -1280,16 +1280,19 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
padding: 0.5em 1em !important;
}
.ck.ck-slash-command-button__text-part {
.ck.ck-slash-command-button__text-part,
.ck.ck-template-form__text-part {
margin-left: 0.5em;
line-height: 1.2em !important;
}
.ck.ck-slash-command-button__text-part > span {
.ck.ck-slash-command-button__text-part > span,
.ck.ck-template-form__text-part > span {
line-height: inherit !important;
}
.ck.ck-slash-command-button__text-part .ck.ck-slash-command-button__description {
.ck.ck-slash-command-button__text-part .ck.ck-slash-command-button__description,
.ck.ck-template-form__text-part .ck-template-form__description {
display: block;
opacity: 0.8;
}

View File

@ -8,4 +8,9 @@ declare module "*?url" {
export default path;
}
declare module "*?raw" {
var content: string;
export default content;
}
declare module "boxicons/css/boxicons.min.css" { }

View File

@ -7,13 +7,14 @@ import { ensureMimeTypesForHighlighting, isSyntaxHighlightEnabled } from "../../
import utils from "../../../services/utils.js";
import emojiDefinitionsUrl from "@triliumnext/ckeditor5/emoji_definitions/en.json?url";
import { copyTextWithToast } from "../../../services/clipboard_ext.js";
import getTemplates from "./snippets.js";
const TEXT_FORMATTING_GROUP = {
label: "Text formatting",
icon: "text"
};
export function buildConfig(): EditorConfig {
export async function buildConfig(): Promise<EditorConfig> {
return {
image: {
styles: {
@ -126,6 +127,9 @@ export function buildConfig(): EditorConfig {
dropdownLimit: Number.MAX_SAFE_INTEGER,
extraCommands: buildExtraCommands()
},
template: {
definitions: await getTemplates()
},
// This value must be kept in sync with the language defined in webpack.config.js.
language: "en"
};
@ -206,6 +210,7 @@ export function buildClassicToolbar(multilineToolbar: boolean) {
"outdent",
"indent",
"|",
"insertTemplate",
"markdownImport",
"cuttonote",
"findAndReplace"
@ -262,6 +267,7 @@ export function buildFloatingToolbar() {
"outdent",
"indent",
"|",
"insertTemplate",
"imageUpload",
"markdownImport",
"specialCharacters",

View File

@ -0,0 +1,105 @@
import debounce from "debounce";
import froca from "../../../services/froca.js";
import type LoadResults from "../../../services/load_results.js";
import search from "../../../services/search.js";
import type { TemplateDefinition } from "@triliumnext/ckeditor5";
import appContext from "../../../components/app_context.js";
import TemplateIcon from "@ckeditor/ckeditor5-icons/theme/icons/template.svg?raw";
import type FNote from "../../../entities/fnote.js";
interface TemplateData {
title: string;
description?: string;
content?: string;
}
let templateCache: Map<string, TemplateData> = new Map();
const debouncedHandleContentUpdate = debounce(handleContentUpdate, 1000);
/**
* Generates the list of snippets based on the user's notes to be passed down to the CKEditor configuration.
*
* @returns the list of templates.
*/
export default async function getTemplates() {
// Build the definitions and populate the cache.
const snippets = await search.searchForNotes("#textSnippet");
const definitions: TemplateDefinition[] = [];
for (const snippet of snippets) {
const { description } = await invalidateCacheFor(snippet);
definitions.push({
title: snippet.title,
data: () => templateCache.get(snippet.noteId)?.content ?? "",
icon: TemplateIcon,
description
});
}
return definitions;
}
async function invalidateCacheFor(snippet: FNote) {
const description = snippet.getLabelValue("textSnippetDescription");
const data: TemplateData = {
title: snippet.title,
description: description ?? undefined,
content: await snippet.getContent()
};
templateCache.set(snippet.noteId, data);
return data;
}
function handleFullReload() {
console.warn("Full text editor reload needed");
appContext.triggerCommand("reloadTextEditor");
}
async function handleContentUpdate(affectedNoteIds: string[]) {
const updatedNoteIds = new Set(affectedNoteIds);
const templateNoteIds = new Set(templateCache.keys());
const affectedTemplateNoteIds = templateNoteIds.intersection(updatedNoteIds);
await froca.getNotes(affectedNoteIds);
let fullReloadNeeded = false;
for (const affectedTemplateNoteId of affectedTemplateNoteIds) {
try {
const template = await froca.getNote(affectedTemplateNoteId);
if (!template) {
console.warn("Unable to obtain template with ID ", affectedTemplateNoteId);
continue;
}
const newTitle = template.title;
if (templateCache.get(affectedTemplateNoteId)?.title !== newTitle) {
fullReloadNeeded = true;
break;
}
await invalidateCacheFor(template);
} catch (e) {
// If a note was not found while updating the cache, it means we need to do a full reload.
fullReloadNeeded = true;
}
}
if (fullReloadNeeded) {
handleFullReload();
}
}
export function updateTemplateCache(loadResults: LoadResults): boolean {
const affectedNoteIds = loadResults.getNoteIds();
// React to creation or deletion of text snippets.
if (loadResults.getAttributeRows().find((attr) =>
attr.type === "label" &&
(attr.name === "textSnippet" || attr.name === "textSnippetDescription"))) {
handleFullReload();
} else if (affectedNoteIds.length > 0) {
// Update content and titles if one of the template notes were updated.
debouncedHandleContentUpdate(affectedNoteIds);
}
return false;
}

View File

@ -18,6 +18,7 @@ import { getMermaidConfig } from "../../services/mermaid.js";
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor, type MentionFeed, type WatchdogConfig } from "@triliumnext/ckeditor5";
import "@triliumnext/ckeditor5/index.css";
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
import { updateTemplateCache } from "./ckeditor/snippets.js";
const mentionSetup: MentionFeed[] = [
{
@ -193,7 +194,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
const finalConfig = {
...editorConfig,
...buildConfig(),
...(await buildConfig()),
...buildToolbarConfig(isClassicEditor),
htmlSupport: {
allow: JSON.parse(options.get("allowedHtmlTags")),
@ -326,7 +327,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
const data = blob?.content || "";
const newContentLanguage = this.note?.getLabelValue("language");
if (this.contentLanguage !== newContentLanguage) {
await this.reinitialize(data);
await this.reinitializeWithData(data);
} else {
this.watchdog.editor?.setData(data);
}
@ -562,7 +563,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
this.refreshIncludedNote(this.$editor, noteId);
}
async reinitialize(data: string) {
async reinitializeWithData(data: string) {
if (!this.watchdog) {
return;
}
@ -572,9 +573,25 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
this.watchdog.editor?.setData(data);
}
async onLanguageChanged() {
async reinitialize() {
const data = this.watchdog.editor?.getData();
await this.reinitialize(data ?? "");
await this.reinitializeWithData(data ?? "");
}
async reloadTextEditorEvent() {
await this.reinitialize();
}
async onLanguageChanged() {
await this.reinitialize();
}
async entitiesReloadedEvent(e: EventData<"entitiesReloaded">) {
await super.entitiesReloadedEvent(e);
if (updateTemplateCache(e.loadResults)) {
await this.reinitialize();
}
}
buildTouchBarCommand(data: CommandListenerData<"buildTouchBar">) {

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@ class="image">
<img style="aspect-ratio:1144/660;" src="Sharing_image.png" width="1144"
height="660">
</figure>
<h2>Features, interaction and limitations</h2>
<ul>
<li>Searching by note title.</li>
@ -34,7 +35,7 @@ class="image">
</thead>
<tbody>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a>
<th><a class="reference-link" href="#root/_help_iPIMuisry3hd">Text</a>
</th>
<td>
<ul>
@ -52,7 +53,7 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">Code</a>
<th><a class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a>
</th>
<td>
<ul>
@ -66,27 +67,27 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_m523cpzocqaD">Saved Search</a>
<th><a class="reference-link" href="#root/_help_m523cpzocqaD">Saved Search</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iRwzGnHPzonm">Relation Map</a>
<th><a class="reference-link" href="#root/_help_iRwzGnHPzonm">Relation Map</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_bdUJEHsAPYQR">Note Map</a>
<th><a class="reference-link" href="#root/_help_bdUJEHsAPYQR">Note Map</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>
<th><a class="reference-link" href="#root/_help_HcABDtFCkbFN">Render Note</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_GTwFsgaA0lCt">Book</a>
<th><a class="reference-link" href="#root/_help_GTwFsgaA0lCt">Book</a>
</th>
<td>
<ul>
@ -100,7 +101,7 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_s1aBHPd79XYj">Mermaid Diagrams</a>
<th><a class="reference-link" href="#root/_help_s1aBHPd79XYj">Mermaid Diagrams</a>
</th>
<td>
<ul>
@ -114,7 +115,7 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_grjYqerjn243">Canvas</a>
<th><a class="reference-link" href="#root/_help_grjYqerjn243">Canvas</a>
</th>
<td>
<ul>
@ -128,12 +129,12 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_1vHRoWCEjj0L">Web View</a>
<th><a class="reference-link" href="#root/_help_1vHRoWCEjj0L">Web View</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_gBbsAeiuUxI5">Mind Map</a>
<th><a class="reference-link" href="#root/_help_gBbsAeiuUxI5">Mind Map</a>
</th>
<td>The diagram is displayed as a vector image.</td>
<td>
@ -143,12 +144,12 @@ class="image">
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_81SGnPGMk7Xc">Geo Map</a>
<th><a class="reference-link" href="#root/_help_81SGnPGMk7Xc">Geo Map</a>
</th>
<td colspan="2">Not supported.</td>
<td>Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_W8vYD3Q1zjCR">File</a>
<th><a class="reference-link" href="#root/_help_W8vYD3Q1zjCR">File</a>
</th>
<td>Basic interaction (downloading the file).</td>
<td>
@ -183,9 +184,11 @@ class="image">
<img src="Sharing_share-single-note.png" alt="Share Note">
</p>
</li>
<li><strong>Access the Shared Note</strong>: The link provided will open the
<li>
<p><strong>Access the Shared Note</strong>: The link provided will open the
note in your browser. If your server is not configured with a public IP,
the URL will refer to <code>localhost (127.0.0.1)</code>.</li>
the URL will refer to <code>localhost (127.0.0.1)</code>.</p>
</li>
</ol>
<h2>Sharing a Note Subtree</h2>
<p>When you share a note, you actually share the entire subtree of notes
@ -337,6 +340,7 @@ for (const attr of parentNote.attributes) {
</tbody>
</table>
</figure>
<h2>Credits</h2>
<p>Since v0.95.0, a new theme was introduced (and enabled by default) which
greatly improves the visual aspect of the Share feature, as well as its

View File

@ -24,6 +24,7 @@
</tbody>
</table>
</figure>
<h2>By adding an attribute to the note</h2>
<p>Simply add the <code>#shareRaw</code> attribute and the note will always
be rendered <em>raw</em> when accessed from the share URL.</p>

View File

@ -146,6 +146,8 @@
<li><code>#publicationYear %= '19[0-9]{2}'</code>: Use the '%=' operator to
match a regular expression (regex). This feature has been available since
Trilium 0.52.</li>
<li><code>note.content %= '\\d{2}:\\d{2} (PM|AM)'</code>: Find notes that
mention a time. Backslashes in a regex must be escaped.</li>
</ul>
<h3>Advanced Use Cases</h3>
<ul>

View File

@ -142,17 +142,31 @@ class="table">
</td>
<td>
<ul>
<li>Indentation</li>
<li>Indentation
<ul>
<li>Markdown import</li>
</ul>
</li>
<li><a class="reference-link" href="#root/_help_2x0ZAX9ePtzV">Cut to subnote</a>
</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_gLt3vA97tMcp">Premium features</a>
</td>
<td>
<ul>
<li><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/gLt3vA97tMcp/_help_ZlN4nump6EbW">Slash Commands</a>
</li>
<li><a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</figure>
<h2>Read-Only vs. Editing Mode</h2>
<p>Text notes are usually opened in edit mode. However, they may open in
read-only mode if the note is too big or the note is explicitly marked

View File

@ -0,0 +1,17 @@
<p>The text editor we are using for <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a> notes
is called CKEditor and it's a commercial product. The core components are
open-source, however they <a href="https://ckeditor.com/docs/trial/latest/index.html">offer quite a few features</a> that
require a commercial license in order to be used.</p>
<p>We have reached out to the CKEditor team in order to obtain a license
in order to have some of these extra features and they have agreed, based
on a signed agreement.</p>
<h2>How the license works</h2>
<p>The license key is stored in the application and it enables the use of
the previously described premium features. The license key has an expiration
date which means that the features can become disabled if using an older
version of the application for extended periods of time.</p>
<h2>Can I opt out of these features?</h2>
<p>At this moment there is no way to disable this features, apart from manually
modifying the source code. If this is a problem, <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">let us know</a>.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

View File

@ -0,0 +1,35 @@
<figure class="image image-style-align-right">
<img style="aspect-ratio:419/571" src="Slash Commands_image.png" width="419"
height="571" />
</figure>
<aside class="admonition note">
<p>This is a premium feature of the editor we are using (CKEditor) and we
benefit from it thanks to an written agreement with the team. See  <a class="reference-link"
href="#root/_help_gLt3vA97tMcp">Premium features</a> for more information.</p>
</aside>
<p>Slash commands is a feature of <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a> notes
which allows easily accessing commonly used commands simply by using the
keyboard, without having to remember dedicated <a class="reference-link"
href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/_help_A9Oc6YKKc65v">Keyboard Shortcuts</a>.</p>
<h2>Interaction</h2>
<ul>
<li>As the name suggests, to trigger the slash commands simply press the <kbd>/</kbd> key
to trigger it. Note that this can be anywhere in a paragraph as long as
it's not part of the word, if it doesn't show up simply press a space and
press the <kbd>/</kbd> key again.</li>
<li>Use <kbd></kbd> and <kbd></kbd> keys to navigate between options.</li>
<li>By default, the full list of commands is displayed.</li>
<li>To search by title or description, simply start typing for an action.</li>
<li>To trigger an action, press the <kbd>Enter</kbd> key.</li>
</ul>
<h2>Integration with other features</h2>
<p>Apart from the common set of commands, some features are specially integrated
with the slash commands:</p>
<ul>
<li>For <a href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_NwBbFdNZ9h7O">admonitions</a>,
each admonition type (e.g. note, tip) will be individually displayed.</li>
<li>Every <a class="reference-link" href="#root/_help_pwc194wlRzcH">Text Snippets</a> will
also appear individually, making it easy to insert them.</li>
</ul>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,56 @@
<figure class="image image-style-align-right">
<img style="aspect-ratio:265/108" src="Text Snippets_image.png" width="265"
height="108" />
</figure>
<aside class="admonition note">
<p>This is a premium feature of the editor we are using (CKEditor) and we
benefit from it thanks to an written agreement with the team. See  <a class="reference-link"
href="#root/_help_gLt3vA97tMcp">Premium features</a> for more information.</p>
</aside>
<p>Text Snippets are closely related to <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>,
but instead of defining the content of an entire note, text snippets are
pieces of formatted text that can easily be inserted in a text note.</p>
<h2>Creating a text snippet</h2>
<p>In the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_oPVyFC7WL2Lp">Note Tree</a>:</p>
<ol>
<li>Right click a note where to place the text snippet.</li>
<li>Select <em>Insert child note</em>.</li>
<li>Select <em>Text snippet</em>.</li>
</ol>
<p>Afterwards, simply type in the content of the note the desired text. The
text can be formatted in the same manner as a normal text note.</p>
<p>The title of the note will become the title of the template. Optionally,
a description can be added in the <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_OFXdgB2nNk1F">Promoted Attributes</a> section.</p>
<h2>Inserting a snippet</h2>
<p>Once a snippet is created, there are two options to insert it:</p>
<ol>
<li>From the <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_nRhnJkTT8cPs">Formatting toolbar</a>,
by looking for the
<img src="1_Text Snippets_image.png" width="19" height="19"
/>button.</li>
<li>Using <a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>:
<ol>
<li>To look for a specific template, start typing the name of the template
(its title).</li>
<li>To look for all the templates, type <code>template</code>.</li>
</ol>
</li>
</ol>
<aside class="admonition tip">
<p>A newly created snippet doesn't appear? Generally it takes up to a few
seconds to refresh the list of templates once you make a change.</p>
<p>If this doesn't happen, <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_s8alTXmpFR61">reload the application</a> and
<a
href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">report the issue</a>to us. </p>
</aside>
<h2>Limitations</h2>
<ul>
<li>Whenever a snippet is created, deleted or its title/description are modified,
all the open text notes will need to be refreshed. This causes a slight
flash for usually under a second, but it can cause some discomfort.</li>
<li>Unlike <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>,
the snippets cannot be limited to a particular <a href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/wArbEsdSae6g/_help_9sRHySam5fXb">workspace</a>.</li>
</ul>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -8,6 +8,7 @@ import migrationService from "./migration.js";
import { t } from "i18next";
import { cleanUpHelp, getHelpHiddenSubtreeData } from "./in_app_help.js";
import buildLaunchBarConfig from "./hidden_subtree_launcherbar.js";
import buildHiddenSubtreeTemplates from "./hidden_subtree_templates.js";
const LBTPL_ROOT = "_lbTplRoot";
const LBTPL_BASE = "_lbTplBase";
@ -257,7 +258,8 @@ function buildHiddenSubtreeDefinition(helpSubtree: HiddenSubtreeItem[]): HiddenS
icon: "bx-help-circle",
children: helpSubtree,
isExpanded: true
}
},
buildHiddenSubtreeTemplates()
]
};
}

View File

@ -0,0 +1,34 @@
import { HiddenSubtreeItem } from "@triliumnext/commons";
export default function buildHiddenSubtreeTemplates() {
const templates: HiddenSubtreeItem = {
id: "_templates",
title: "Built-in templates",
type: "book",
children: [
{
id: "_template_text_snippet",
type: "text",
title: "Text Snippet",
icon: "bx-align-left",
attributes: [
{
name: "template",
type: "label"
},
{
name: "textSnippet",
type: "label"
},
{
name: "label:textSnippetDescription",
type: "label",
value: "promoted,alias=Description,single,text"
}
]
}
]
};
return templates;
}

View File

@ -257,7 +257,7 @@ async function configureWebContents(webContents: WebContents, spellcheckEnabled:
}
function getIcon() {
return path.join(RESOURCE_DIR, "images/app-icons/png/256x256" + (isDev ? "-dev" : "") + ".png");
return path.join(RESOURCE_DIR, "../public/assets/icon.png");
}
async function createSetupWindow() {

View File

@ -1,2 +1,10 @@
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
main a {
text-decoration: revert;
}
a.rounded-full, a.rounded-xl {
text-decoration: none;
}

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
<body data-sveltekit-preload-data="hover" class="dark:bg-black dark:text-white">
%sveltekit.body%
</body>
</html>

View File

@ -41,6 +41,14 @@ export const downloadMatrix: DownloadMatrix = {
},
zip: {
name: "Portable (.zip)"
},
scoop: {
name: "Scoop",
url: "https://scoop.sh/#/apps?q=triliumnext"
},
winget: {
name: "Winget",
url: "https://github.com/microsoft/winget-pkgs/tree/master/manifests/t/TriliumNext/Notes/"
}
}
},
@ -66,6 +74,14 @@ export const downloadMatrix: DownloadMatrix = {
},
zip: {
name: "Portable (.zip)"
},
nixpkgs: {
name: "nixpkgs",
url: "https://search.nixos.org/packages?query=trilium-next"
},
aur: {
name: "AUR",
url: "https://aur.archlinux.org/packages/triliumnext-bin"
}
}
},
@ -107,6 +123,10 @@ export const downloadMatrix: DownloadMatrix = {
name: "ARM (.tar.xz)",
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-Server-v${version}-linux-arm64.tar.xz`
},
nixos: {
name: "NixOS module",
url: "https://search.nixos.org/options?query=trilium-server"
}
}
},
pikapod: {
@ -129,7 +149,8 @@ export const downloadMatrix: DownloadMatrix = {
export function buildDownloadUrl(app: App, platform: Platform, format: string, architecture: Architecture): string {
if (app === "desktop") {
return `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-v${version}-${platform}-${architecture}.${format}`;
return downloadMatrix.desktop[platform]?.downloads[format].url ??
`https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-v${version}-${platform}-${architecture}.${format}`;
} else if (app === "server") {
return downloadMatrix.server[platform]?.downloads[format].url ?? "#";
} else {

View File

@ -7,8 +7,10 @@
<Header />
<main>
{@render children()}
</main>
<footer class="container mx-auto bg-white mt-2 py-6 text-sm text-center text-gray-500">
<footer class="container max-w-screen mx-0 w-full bg-white dark:bg-gray-900 mt-2 py-6 text-sm text-center text-gray-500">
&copy; 2024-2025 <a href="https://github.com/eliandoran" class="text-blue-500 hover:underline">Elian Doran</a> and the <a href="https://github.com/TriliumNext/Notes/graphs/contributors" class="text-blue-500 hover:underline">team</a>. <br/> &copy; 2017-2024 <a href="https://github.com/zadam" class="text-blue-500 hover:underline">Adam Zivner</a>.
</footer>

View File

@ -1,8 +1,16 @@
<script>
import DownloadNow from "./download-now.svelte";
import FeatureBlock from "./feature-block.svelte";
</script>
<section class="relative overflow-hidden bg-gradient-to-br from-white to-violet-50">
<svelte:head>
<title>Trilium Notes</title>
<!-- TODO: description?
<meta name="description" content="This is where the description goes for search engines" />
-->
</svelte:head>
<section class="relative overflow-hidden bg-gradient-to-br from-white dark:from-black to-violet-50 dark:to-violet-900">
<!-- Bokeh background circles -->
<div class="absolute inset-0 pointer-events-none z-0">
<div class="absolute w-72 h-72 bg-violet-300 opacity-30 rounded-full blur-3xl top-[-50px] left-[-80px]"></div>
@ -15,10 +23,12 @@
<!-- Left: Text Content -->
<div class="md:w-1/3">
<h2 class="text-4xl font-bold mb-4 text-gray-900">Organize Your Thoughts.<br/> Build Your Knowledge.</h2>
<p class="text-lg mb-6 text-gray-700">
<h2 class="text-4xl font-bold mb-4 text-gray-900 dark:text-white">Organize Your Thoughts.<br/> Build Your Knowledge.</h2>
<p class="text-lg mb-6 text-gray-700 dark:text-gray-300">
Trilium Notes helps you build and organize complex personal knowledge bases effortlessly.
Its unique tree structure, rich editing tools, and powerful search features make managing your information intuitive and flexible.
<!-- TODO: remove the squiggly autocorrect lines in the screenshot!! -->
<!-- TODO: dark mode screenshot -->
</p>
<div class="flex items-center gap-6">
<DownloadNow big />
@ -40,48 +50,72 @@
<h2 class="text-3xl font-bold text-center mb-12">Beyond Text: Smarter Note Types</h2>
<div class="grid md:grid-cols-2 gap-10">
<!-- Canvas Notes -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/canvas.png" alt="Canvas Note Screenshot" class="w-full h-56 object-cover object-top">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Canvas Notes</h3>
<p class="text-gray-600">Draw and arrange elements freely using an Excalidraw-powered canvas — ideal for diagrams, sketches, and visual planning.</p>
</div>
<FeatureBlock
imgSrc="/note-types/canvas.png"
imgAlt="Canvas Note Screenshot"
title="Canvas Notes"
text="Draw and arrange elements freely using an Excalidraw-powered canvas — ideal for diagrams, sketches, and visual planning."
/>
<FeatureBlock
imgSrc="/note-types/mermaid.png"
imgAlt="Mermaid Diagram Screenshot"
title="Mermaid Diagrams"
text="Render flowcharts, Gantt charts, and sequence diagrams with Mermaid markdown syntax directly in your notes."
/>
<FeatureBlock
imgSrc="/note-types/geo-map.png"
imgAlt="Geo Map Screenshot"
title="Geo Maps"
text="Plot locations and GPX tracks to visualize geography-linked notes and movement patterns on interactive maps."
/>
<FeatureBlock
imgSrc="/note-types/mind-map.png"
imgAlt="Mind Map Screenshot"
title="Mind Maps"
text="Organize ideas visually using a drag-and-drop mind map editor powered by Mind Elixir."
/>
</div>
<!-- Mermaid Diagrams -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/mermaid.png" alt="Mermaid Diagram Screenshot" class="w-full h-56 object-cover object-top">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Mermaid Diagrams</h3>
<p class="text-gray-600">Render flowcharts, Gantt charts, and sequence diagrams with Mermaid markdown syntax directly in your notes.</p>
</div>
</div>
<h2 class="text-3xl font-bold text-center mb-12">Technical Features</h2>
<!-- Geo Maps -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/geo-map.png" alt="Geo Map Screenshot" class="w-full h-56 object-cover">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Geo Maps</h3>
<p class="text-gray-600">Plot locations and GPX tracks to visualize geography-linked notes and movement patterns on interactive maps.</p>
</div>
</div>
<div class="grid md:grid-cols-2 gap-10">
<FeatureBlock
imgSrc="/technical-features/sync-server.png"
imgAlt="TODO"
title="Synchronization Server"
text="Seamless mirroring of changes acroll all devices."
/>
<!-- Mind Maps -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/mind-map.png" alt="Mind Map Screenshot" class="w-full h-56 object-cover">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Mind Maps</h3>
<p class="text-gray-600">Organize ideas visually using a drag-and-drop mind map editor powered by Mind Elixir.</p>
</div>
</div>
<FeatureBlock
imgSrc="/technical-features/cross-platform.png"
imgAlt="TODO, maybe some icons"
title="Cross-platform App + Web UI"
text="Use as Electron application or in your browser."
/>
<FeatureBlock
imgSrc="/technical-features/scripting.png"
imgAlt="TODO"
title="Scripting"
text="Custom UI widgets and a REST API for automation."
/>
<FeatureBlock
imgSrc="/technical-features/grafana-metrics.png"
imgAlt="Mind Map Screenshot"
title="Grafana Metrics"
text="Measure database metrics over time."
/>
</div>
</section>
<section class="mt-20 max-w-6xl mx-auto px-4">
<h2 class="text-3xl font-bold text-center mb-12">Feature Highlights</h2>
<div class="grid gap-12 md:grid-cols-2 max-w-4xl mx-auto text-gray-700">
<div class="grid gap-12 md:grid-cols-2 max-w-4xl mx-auto text-gray-700 dark:text-gray-300">
<!-- Organization & Navigation -->
<div>
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Organization & Navigation</h3>
@ -109,7 +143,6 @@
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Security & Sync</h3>
<ul class="list-disc list-inside space-y-3">
<li>Direct OpenID and TOTP integration for secure login.</li>
<li>Synchronization with self-hosted and third-party servers.</li>
<li>Strong note encryption with per-note granularity.</li>
<li>Sharing notes publicly on the internet.</li>
</ul>
@ -120,10 +153,8 @@
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Advanced & Customization</h3>
<ul class="list-disc list-inside space-y-3">
<li>Relation maps and link maps to visualize notes.</li>
<li>Scripting support and REST API for automation.</li>
<li>Touch-optimized mobile frontend and dark/user themes.</li>
<li>Customizable UI with sidebar buttons and user widgets.</li>
<li>Metrics with Grafana dashboard integration.</li>
<li>Scales efficiently beyond 100,000 notes.</li>
</ul>
</div>
@ -131,13 +162,13 @@
</section>
<section class="bg-violet-50 py-16 mt-24">
<section class="bg-violet-50 dark:bg-black py-16 mt-24">
<div class="container mx-auto text-center px-4">
<h2 class="text-3xl font-bold mb-4">Ready to get started with Trilium Notes?</h2>
<p class="text-lg text-gray-700 mb-8">Build your personal knowledge base with powerful features and full privacy.</p>
<p class="text-lg text-gray-700 dark:text-gray-200 mb-8">Build your personal knowledge base with powerful features and full privacy.</p>
<div class="flex justify-center gap-6">
<a href="#" class="py-3 px-6 bg-violet-600 text-white font-semibold rounded-full shadow hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75">
<a href="download" class="py-3 px-6 bg-violet-600 text-white font-semibold rounded-full shadow hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75">
Download Now
</a>
</div>

View File

@ -7,13 +7,20 @@
let architecture = getArchitecture();
</script>
<div class="bg-gray-50 py-20">
<svelte:head>
<title>Trilium Notes: Download</title>
<!-- TODO: description?
<meta name="description" content="This is where the description goes for search engines" />
-->
</svelte:head>
<div class="bg-gray-50 dark:bg-black py-20">
<section class="max-w-6xl mx-auto px-4">
<h2 class="text-4xl font-bold text-center text-gray-900 mb-12">Download the desktop application</h2>
<h2 class="text-4xl font-bold text-center text-gray-900 dark:text-white mb-12">Download the desktop application</h2>
<!-- Architecture pill selector -->
<div class="col-span-3 flex justify-center items-center gap-3 mb-6">
<span class="text-gray-600 font-medium mr-2">Architecture:</span>
<span class="text-gray-600 dark:text-gray-300 font-medium mr-2">Architecture:</span>
<div class="inline-flex bg-violet-100 rounded-full shadow p-1">
{#each architectures as arch}
<button class="py-2 px-6 rounded-full font-semibold focus:outline-none transition
@ -28,7 +35,7 @@
<div class="grid md:grid-cols-3 gap-10">
{#each Object.entries(downloadMatrix.desktop) as [platformId, platform]}
{@const textColor = (platformId === "windows" ? "text-blue-600" : platformId === "linux" ? "text-violet-600" : "text-gray-800")}
{@const textColor = (platformId === "windows" ? "text-blue-600" : platformId === "linux" ? "text-violet-600" : "text-gray-800 dark:text-gray-100")}
{@const bgColor = (platformId === "windows" ? "bg-blue-600" : platformId === "linux" ? "bg-violet-600" : "bg-gray-800")}
{@const hoverColor = (platformId === "windows" ? "hover:bg-blue-700" : platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")}
<DownloadCard app="desktop"
@ -39,11 +46,11 @@
</section>
<section class="max-w-4xl mx-auto px-4 mt-10">
<h2 class="text-3xl font-bold text-center text-gray-900 mb-8">Set up a server for access on multiple devices</h2>
<h2 class="text-3xl font-bold text-center text-gray-900 dark:text-white mb-8">Set up a server for access on multiple devices</h2>
<div class="grid md:grid-cols-2 gap-10">
{#each Object.entries(downloadMatrix.server) as [platformId, platform]}
{@const textColor = (platformId === "linux" ? "text-violet-600" : "text-gray-800")}
{@const textColor = (platformId === "linux" ? "text-violet-600" : "text-gray-800 dark:text-gray-100")}
{@const bgColor = (platformId === "linux" ? "bg-violet-600" : "bg-gray-800")}
{@const hoverColor = (platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")}
<DownloadCard app="server"
@ -53,4 +60,6 @@
</div>
</section>
<!-- TODO: mention mobile support here? (alpha Android app / mobile web view) -->
</div>

View File

@ -11,16 +11,16 @@
const recommended = Object.entries(platform.downloads).find((e) => e[1].recommended);
</script>
<div class="bg-white border border-gray-200 rounded-2xl shadow-lg p-8 flex flex-col items-start">
<div class="bg-white dark:bg-gray-900 border border-gray-200 rounded-2xl shadow-lg p-8 flex flex-col items-start">
<h3 class="text-2xl font-semibold {textColor} mb-2">{typeof platform.title === "object" ? platform.title[architecture] : platform.title}</h3>
<p class="text-gray-700 mb-12">{typeof platform.title === "object" ? platform.description[architecture] : platform.description}</p>
<p class="text-gray-700 dark:text-gray-200 mb-12">{typeof platform.title === "object" ? platform.description[architecture] : platform.description}</p>
<div class="space-y-2 mt-auto w-full">
{#if recommended}
<a href={buildDownloadUrl(app, platformId as Platform, recommended[0], architecture)} class="mt-auto block text-center {bgColor} {hoverColor} text-white font-medium py-2 px-5 rounded-full shadow transition">
{recommended[1].name}
</a>
{/if}
<div class="flex justify-center gap-4 text-sm {textColor} mt-2">
<div class="flex flex-wrap justify-center gap-4 text-sm {textColor} mt-2">
{#each Object.entries(platform.downloads).filter((e) => !e[1].recommended) as [format, download]}
<a href={buildDownloadUrl(app, platformId as Platform, format, architecture)} class="hover:underline block">
{download.name}

View File

@ -0,0 +1,14 @@
<script>
export let imgSrc = "/404.png";
export let imgAlt = "screenshot";
export let title = "title";
export let text = "text";
</script>
<div class="bg-white dark:bg-gray-900 rounded-xl shadow overflow-hidden">
<img src="{imgSrc}" alt="{imgAlt}" class="w-full h-56 object-cover object-top">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">{title}</h3>
<p class="text-gray-600 dark:text-gray-300">{text}</p>
</div>
</div>

View File

@ -2,7 +2,7 @@
import DownloadNow from "./download-now.svelte";
</script>
<header class="header bg-white sticky top-0 z-50 shadow">
<header class="header bg-white dark:bg-gray-900 sticky dark:text-white top-0 z-50 shadow">
<div class="container mx-auto flex items-center py-4">
<a href="/" class="flex items-center gap-x-2 w-100">
<img src="icon-color.svg" alt="Trilium Notes Logo" class="w-12 h-12">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 40 B

View File

@ -0,0 +1 @@
../../../apps/client/src/assets/icon.png

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 40 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 KiB

View File

@ -0,0 +1 @@
../../../../docs/User Guide/User Guide/Advanced Usage/1_Metrics_image.png

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
# Nix flake
Since TriliumNext 0.94.1, the desktop and server applications can be built using [Nix](https://nixos.org/).
## System requirements
Installation of Nix on Mac or Linux ([download page](https://nixos.org/download/)). About 3-4 gigabytes of additional storage space, for build artifacts.
## Run directly
Using [nix run](https://nix.dev/manual/nix/stable/command-ref/new-cli/nix3-run.html), the desktop app can be started as: `nix run github:TriliumNext/Notes/v0.95.0`
Running the server requires explicitly specifying the desired package: `nix run github:TriliumNext/Notes/v0.95.0#server`
Instead of a version (`v0.95.0` above), you can also specify a commit hash (or a branch name). This makes it easy to test development builds.
## Install on NixOS
Add to your `flake.nix`:
```
{
inputs = {
nixpkgs.url = # ...;
trilium-notes = {
url = "github:TriliumNext/Notes/v0.95.0";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
# ...
trilium-notes,
...
}:
{
nixosConfigurations = {
"nixos" = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
];
specialArgs = {
inherit
trilium-notes
;
};
};
};
};
}
```
Add to your `configuration.nix`:
```
{
# ...
trilium-notes,
...
}:
{
# ...
services.trilium-server.package = trilium-notes.packages.x86_64-linux.server;
environment.systemPackages = [
trilium-notes.packages.x86_64-linux.desktop
];
}
```
The flake aims to be compatible with the latest NixOS stable and unstable.

View File

@ -1,4 +1,4 @@
# Build information
* Provides context about when the build was made and the corresponding Git revision.
* The information is displayed to the client when going in the about dialog.
* The build information is hard-coded in `src/services/build.ts`. This file is generated automatically via `npm run update-build-info` which itself is run automatically whenever making a build in the CI, or a [local delivery](../Build%20deliveries%20locally.md).
* The build information is hard-coded in `src/services/build.ts`. This file is generated automatically via `npm run update-build-info` which itself is run automatically whenever making a build in the CI, or a [local delivery](../Old%20documentation/Build%20deliveries%20locally.md).

View File

@ -17,7 +17,7 @@ These are stored in `images`:
## App icons
<figure class="table"><table><thead><tr><th>Name</th><th>Resolution</th><th>Description</th></tr></thead><tbody><tr><td><code>ios/apple-touch-icon.png</code></td><td>180x180</td><td>Used as <code>apple-touch-icon</code>, but only in <code>login.ejs</code> and <code>set_password.ejs</code> for some reason.</td></tr><tr><td><code>mac/icon.icns</code></td><td>512x512</td><td>Provided as <code>--icon</code> to <code>electron-packager</code> for <code>mac-arm64</code> and <code>mac-x64</code> <a href="../Build%20deliveries%20locally.md">builds</a>.</td></tr><tr><td><code>png/128x128.png</code></td><td>128x128</td><td>Used in <code>linux-x64</code> <a href="../Build%20deliveries%20locally.md">build</a>, to provide an <code>icon.png</code>.</td></tr><tr><td><code>png/256x256-dev.png</code></td><td>256x256</td><td>Used by the Electron window icon, if in dev mode.</td></tr><tr><td><code>png/256x256.png</code></td><td>Used by the Electron window icon, if not in dev mode.</td></tr><tr><td><code>win/icon.ico</code></td><td><ul><li>ICO 16x16</li><li>ICO 32x32</li><li>ICO 48x48</li><li>ICO 64x64</li><li>ICO 128x128</li><li>PNG 256x256</li></ul></td><td><ul><li>Used by the <code>win-x64</code> <a href="../Build%20deliveries%20locally.md">build</a>.</li><li>Used by Squirrel Windows installer for: setup icon, app icon, control panel icon</li><li>Used as the favicon.</li></ul></td></tr><tr><td><code>win/setup-banner.gif</code></td><td>640x480</td><td>Used by the Squirrel Windows installer during the installation process. Has only one frame.</td></tr></tbody></table></figure>
<figure class="table"><table><thead><tr><th>Name</th><th>Resolution</th><th>Description</th></tr></thead><tbody><tr><td><code>ios/apple-touch-icon.png</code></td><td>180x180</td><td>Used as <code>apple-touch-icon</code>, but only in <code>login.ejs</code> and <code>set_password.ejs</code> for some reason.</td></tr><tr><td><code>mac/icon.icns</code></td><td>512x512</td><td>Provided as <code>--icon</code> to <code>electron-packager</code> for <code>mac-arm64</code> and <code>mac-x64</code> <a href="../Old%20documentation/Build%20deliveries%20locally.md">builds</a>.</td></tr><tr><td><code>png/128x128.png</code></td><td>128x128</td><td>Used in <code>linux-x64</code> <a href="../Old%20documentation/Build%20deliveries%20locally.md">build</a>, to provide an <code>icon.png</code>.</td></tr><tr><td><code>png/256x256-dev.png</code></td><td>256x256</td><td>Used by the Electron window icon, if in dev mode.</td></tr><tr><td><code>png/256x256.png</code></td><td>Used by the Electron window icon, if not in dev mode.</td></tr><tr><td><code>win/icon.ico</code></td><td><ul><li>ICO 16x16</li><li>ICO 32x32</li><li>ICO 48x48</li><li>ICO 64x64</li><li>ICO 128x128</li><li>PNG 256x256</li></ul></td><td><ul><li>Used by the <code>win-x64</code> <a href="../Old%20documentation/Build%20deliveries%20locally.md">build</a>.</li><li>Used by Squirrel Windows installer for: setup icon, app icon, control panel icon</li><li>Used as the favicon.</li></ul></td></tr><tr><td><code>win/setup-banner.gif</code></td><td>640x480</td><td>Used by the Squirrel Windows installer during the installation process. Has only one frame.</td></tr></tbody></table></figure>
## Additional locations where the branding is used

Some files were not shown because too many files have changed in this diff Show More