mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 17:26:38 +01:00
Compare commits
9 Commits
v0.24.3-be
...
v0.24.4-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e062ab34 | ||
|
|
3a06493459 | ||
|
|
8159564885 | ||
|
|
8ce3c1a480 | ||
|
|
dbc93f4a79 | ||
|
|
92ffe321aa | ||
|
|
6cb7d0098e | ||
|
|
bdcb4361b2 | ||
|
|
15366d37d7 |
@@ -18,6 +18,7 @@ See other pictures in [screenshot tour](https://github.com/zadam/trilium/wiki/Sc
|
||||
* Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts)
|
||||
* [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server
|
||||
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes)
|
||||
* [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) for visualizing notes and their relations
|
||||
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases)
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* [Night theme](https://github.com/zadam/trilium/wiki/Themes)
|
||||
@@ -31,10 +32,6 @@ Trilium is provided as either desktop application ([Electron](https://electronjs
|
||||
* If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation).
|
||||
* Currently only recent Chrome and Firefox are supported (tested) browsers.
|
||||
|
||||
## Status
|
||||
|
||||
Trilium is beta quality software. While it is reasonably feature complete and is tested by its author, it lacks proper testing by more users. It's not yet recommended for daily use, but testing and experimentation is encouraged.
|
||||
|
||||
## Documentation
|
||||
|
||||
[See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/)
|
||||
@@ -6,6 +6,7 @@ const log = require('./src/services/log');
|
||||
const cls = require('./src/services/cls');
|
||||
const url = require("url");
|
||||
const port = require('./src/services/port');
|
||||
const appIconService = require('./src/services/app_icon');
|
||||
|
||||
const app = electron.app;
|
||||
const globalShortcut = electron.globalShortcut;
|
||||
@@ -13,6 +14,8 @@ const globalShortcut = electron.globalShortcut;
|
||||
// Adds debug features like hotkeys for triggering dev tools and reload
|
||||
require('electron-debug')();
|
||||
|
||||
appIconService.installLocalAppIcon();
|
||||
|
||||
// Prevent window being garbage collected
|
||||
let mainWindow;
|
||||
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.24.2-beta",
|
||||
"version": "0.24.3-beta",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -10821,9 +10821,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz",
|
||||
"integrity": "sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz",
|
||||
"integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.24.3-beta",
|
||||
"version": "0.24.4-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
|
||||
@@ -97,14 +97,19 @@ function registerEntrypoints() {
|
||||
|
||||
$(document).bind('keydown', 'ctrl+f', () => {
|
||||
if (utils.isElectron()) {
|
||||
alert("In page search doesn't work in this beta");
|
||||
const $searchWindowWebview = $(".electron-in-page-search-window");
|
||||
$searchWindowWebview.show();
|
||||
|
||||
// const searchInPage = require('electron-in-page-search').default;
|
||||
// const remote = require('electron').remote;
|
||||
//
|
||||
// const inPageSearch = searchInPage(remote.getCurrentWebContents());
|
||||
//
|
||||
// inPageSearch.openSearchWindow();
|
||||
const searchInPage = require('electron-in-page-search').default;
|
||||
const {remote} = require('electron');
|
||||
|
||||
const inPageSearch = searchInPage(remote.getCurrentWebContents(), {
|
||||
searchWindowWebview: $searchWindowWebview[0],
|
||||
//openDevToolsOfSearchWindow: true,
|
||||
customCssPath: '/libraries/electron-in-page-search/default-style.css'
|
||||
});
|
||||
|
||||
inPageSearch.openSearchWindow();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function setupTooltip() {
|
||||
container: 'body',
|
||||
placement: 'auto',
|
||||
trigger: 'manual',
|
||||
boundariesElement: 'window',
|
||||
boundary: 'window',
|
||||
title: html,
|
||||
html: true
|
||||
});
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Meiryo", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inpage-search-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 8px;
|
||||
padding: 10px;
|
||||
border: solid #aaaaaa 1px;
|
||||
border-radius: 10px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.inpage-search-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.inpage-search-matches {
|
||||
color: #999;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.inpage-search-back {
|
||||
margin-left: 2px;
|
||||
padding-left: 6px;
|
||||
padding-right: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-forward {
|
||||
padding-left: 2px;
|
||||
padding-right: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-close {
|
||||
margin-left: 4px;
|
||||
padding: 0 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-back:hover,
|
||||
.inpage-search-forward:hover,
|
||||
.inpage-search-close:hover {
|
||||
background-color: #e2e0e2;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes" />
|
||||
<link href="/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="inpage-search-body">
|
||||
<input class="inpage-search-input form-control form-control-sm" type="search" placeholder="Search..." autocomplete="off" autofocus/>
|
||||
|
||||
<div class="inpage-search-matches">0/0</div>
|
||||
|
||||
<div class="inpage-search-back" title="Previous result"><</div>
|
||||
|
||||
<div class="inpage-search-forward" title="Next result">></div>
|
||||
|
||||
<div class="inpage-search-close" title="Close search">✕</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>var exports = {}</script>
|
||||
</html>
|
||||
@@ -77,9 +77,12 @@ body {
|
||||
overflow: auto;
|
||||
flex-basis: content;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.note-detail-component {
|
||||
flex-grow: 100;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -211,12 +214,12 @@ div.ui-tooltip {
|
||||
*/
|
||||
.electron-in-page-search-window {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
border: solid grey 1px;
|
||||
background-color: white;
|
||||
width: 300px;
|
||||
height: 36px;
|
||||
top: 45px;
|
||||
right: 10px;
|
||||
width: 360px;
|
||||
height: 55px;
|
||||
display: none;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -344,11 +347,11 @@ div.ui-tooltip {
|
||||
#children-overview {
|
||||
flex-grow: 1000;
|
||||
flex-shrink: 1000;
|
||||
flex-basis: 0px;
|
||||
flex-basis: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
height: 100px;
|
||||
height: 110px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -528,12 +531,12 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
.context-menu-container {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.context-menu .dropdown-item {
|
||||
padding: 2px 10px 2px 10px;
|
||||
#context-menu-container .dropdown-item {
|
||||
padding: 0 7px 0 10px;
|
||||
}
|
||||
|
||||
/* if modal height overflows, then only modal body scrolls */
|
||||
@@ -542,6 +545,11 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* this should help with tooltip flickering */
|
||||
.tooltip {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
background-color: #fbfbfb !important;
|
||||
max-width: 400px;
|
||||
|
||||
64
src/services/app_icon.js
Normal file
64
src/services/app_icon.js
Normal file
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
|
||||
const path = require('path');
|
||||
const {APP_PNG_ICON_DIR, ELECTRON_APP_ROOT_DIR} = require("./resource_dir");
|
||||
const log = require("./log");
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const config = require('./config');
|
||||
|
||||
const template = `[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Trilium Notes
|
||||
Icon=#APP_PNG_ICON_DIR#/128x128.png
|
||||
Exec=#EXE_PATH#
|
||||
Categories=Office
|
||||
Terminal=false
|
||||
`;
|
||||
|
||||
/**
|
||||
* Installs .desktop icon into standard ~/.local/share/applications directory.
|
||||
* We overwrite this file during every run as it might have been updated.
|
||||
*/
|
||||
function installLocalAppIcon() {
|
||||
if (["win32", "darwin"].includes(os.platform()) || (config.General && config.General.noDesktopIcon)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const desktopDir = path.resolve(os.homedir(), '.local/share/applications');
|
||||
|
||||
fs.stat(desktopDir, function (err, stats) {
|
||||
if (err) {
|
||||
// Directory doesn't exist so we won't attempt to create the .desktop file
|
||||
return;
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
const desktopFilePath = path.resolve(desktopDir, "trilium-notes.desktop");
|
||||
|
||||
fs.writeFile(desktopFilePath, getDesktopFileContent(), function (err) {
|
||||
if (err) {
|
||||
log.error("Desktop icon installation to ~/.local/share/applications failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getDesktopFileContent() {
|
||||
return template
|
||||
.replace("#APP_PNG_ICON_DIR#", escapePath(APP_PNG_ICON_DIR))
|
||||
.replace("#EXE_PATH#", escapePath(getExePath()));
|
||||
}
|
||||
|
||||
function escapePath(path) {
|
||||
return path.replace(" ", "\\ ");
|
||||
}
|
||||
|
||||
function getExePath() {
|
||||
return path.resolve(ELECTRON_APP_ROOT_DIR, 'trilium');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
installLocalAppIcon
|
||||
};
|
||||
@@ -1 +1 @@
|
||||
module.exports = { buildDate:"2018-11-20T13:01:41+01:00", buildRevision: "0019865807db83621dab71b206d5ea80ba29f002" };
|
||||
module.exports = { buildDate:"2018-11-21T23:47:09+01:00", buildRevision: "3a064934598b70878f6da4c11c0ceb84ef18db57" };
|
||||
|
||||
@@ -80,7 +80,7 @@ function findNotes(query) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// for leaf note it doesn't matter if "archived" label inheritable or not
|
||||
// for leaf note it doesn't matter if "archived" label is inheritable or not
|
||||
if (noteId in archived) {
|
||||
continue;
|
||||
}
|
||||
@@ -113,11 +113,28 @@ function findNotes(query) {
|
||||
}
|
||||
}
|
||||
|
||||
results.sort((a, b) => a.title < b.title ? -1 : 1);
|
||||
// sort results by depth of the note. This is based on the assumption that more important results
|
||||
// are closer to the note root.
|
||||
results.sort((a, b) => {
|
||||
if (a.pathArray.length === b.pathArray.length) {
|
||||
return a.title < b.title ? -1 : 1;
|
||||
}
|
||||
|
||||
highlightResults(results, allTokens);
|
||||
return a.pathArray.length < b.pathArray.length ? -1 : 1;
|
||||
});
|
||||
|
||||
return results;
|
||||
const apiResults = results.slice(0, 200).map(res => {
|
||||
return {
|
||||
noteId: res.noteId,
|
||||
branchId: res.branchId,
|
||||
path: res.pathArray.join('/'),
|
||||
title: res.titleArray.join(' / ')
|
||||
};
|
||||
});
|
||||
|
||||
highlightResults(apiResults, allTokens);
|
||||
|
||||
return apiResults;
|
||||
}
|
||||
|
||||
function search(noteId, tokens, path, results) {
|
||||
@@ -125,15 +142,14 @@ function search(noteId, tokens, path, results) {
|
||||
const retPath = getSomePath(noteId, path);
|
||||
|
||||
if (retPath) {
|
||||
const noteTitle = getNoteTitleForPath(retPath);
|
||||
const thisNoteId = retPath[retPath.length - 1];
|
||||
const thisParentNoteId = retPath[retPath.length - 2];
|
||||
|
||||
results.push({
|
||||
noteId: thisNoteId,
|
||||
branchId: childParentToBranchId[`${thisNoteId}-${thisParentNoteId}`],
|
||||
title: noteTitle,
|
||||
path: retPath.join('/')
|
||||
pathArray: retPath,
|
||||
titleArray: getNoteTitleArrayForPath(retPath)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -146,10 +162,6 @@ function search(noteId, tokens, path, results) {
|
||||
}
|
||||
|
||||
for (const parentNoteId of parents) {
|
||||
if (results.length >= 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
// archived must be inheritable
|
||||
if (archived[parentNoteId] === 1) {
|
||||
continue;
|
||||
@@ -192,12 +204,12 @@ function getNoteTitle(noteId, parentNoteId) {
|
||||
return (prefix ? (prefix + ' - ') : '') + title;
|
||||
}
|
||||
|
||||
function getNoteTitleForPath(path) {
|
||||
function getNoteTitleArrayForPath(path) {
|
||||
const titles = [];
|
||||
|
||||
if (path[0] === 'root') {
|
||||
if (path.length === 1) {
|
||||
return getNoteTitle('root');
|
||||
return [ getNoteTitle('root') ];
|
||||
}
|
||||
else {
|
||||
path = path.slice(1);
|
||||
@@ -213,6 +225,12 @@ function getNoteTitleForPath(path) {
|
||||
parentNoteId = noteId;
|
||||
}
|
||||
|
||||
return titles;
|
||||
}
|
||||
|
||||
function getNoteTitleForPath(path) {
|
||||
const titles = getNoteTitleArrayForPath(path);
|
||||
|
||||
return titles.join(' / ');
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ const fs = require('fs');
|
||||
|
||||
const RESOURCE_DIR = path.resolve(__dirname, "../..");
|
||||
|
||||
// where "trilium" executable is
|
||||
const ELECTRON_APP_ROOT_DIR = path.resolve(RESOURCE_DIR, "../..");
|
||||
const DB_INIT_DIR = path.resolve(RESOURCE_DIR, "db");
|
||||
const APP_PNG_ICON_DIR = path.resolve(RESOURCE_DIR, "src/public/images/app-icons/png");
|
||||
|
||||
if (!fs.existsSync(DB_INIT_DIR)) {
|
||||
log.error("Could not find DB initialization directory: " + DB_INIT_DIR);
|
||||
@@ -21,5 +24,7 @@ if (!fs.existsSync(MIGRATIONS_DIR)) {
|
||||
module.exports = {
|
||||
RESOURCE_DIR,
|
||||
MIGRATIONS_DIR,
|
||||
DB_INIT_DIR
|
||||
DB_INIT_DIR,
|
||||
ELECTRON_APP_ROOT_DIR,
|
||||
APP_PNG_ICON_DIR
|
||||
};
|
||||
@@ -18,9 +18,9 @@
|
||||
<% include image.ejs %>
|
||||
|
||||
<% include relation_map.ejs %>
|
||||
</div>
|
||||
|
||||
<div id="children-overview"></div>
|
||||
<div id="children-overview"></div>
|
||||
</div>
|
||||
|
||||
<div id="attribute-list">
|
||||
<button class="btn btn-sm show-attributes-button">Attributes:</button>
|
||||
|
||||
@@ -187,6 +187,8 @@
|
||||
<% include dialogs/confirm.ejs %>
|
||||
</div>
|
||||
|
||||
<webview class="electron-in-page-search-window" nodeintegration disablewebsecurity src="/libraries/electron-in-page-search/search-window.html"></webview>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.baseApiUrl = 'api/';
|
||||
window.glob = {
|
||||
|
||||
Reference in New Issue
Block a user