mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
Merge branch 'beta'
# Conflicts: # package.json # src/public/app/layouts/desktop_layout.js
This commit is contained in:
commit
5c10fc26be
@ -17,6 +17,7 @@ import SqlResultWidget from "../widgets/sql_result.js";
|
|||||||
import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js";
|
import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js";
|
||||||
import FilePropertiesWidget from "../widgets/ribbon_widgets/file_properties.js";
|
import FilePropertiesWidget from "../widgets/ribbon_widgets/file_properties.js";
|
||||||
import ImagePropertiesWidget from "../widgets/ribbon_widgets/image_properties.js";
|
import ImagePropertiesWidget from "../widgets/ribbon_widgets/image_properties.js";
|
||||||
|
import CanvasPropertiesWidget from "../widgets/ribbon_widgets/canvas_properties.js";
|
||||||
import NotePropertiesWidget from "../widgets/ribbon_widgets/note_properties.js";
|
import NotePropertiesWidget from "../widgets/ribbon_widgets/note_properties.js";
|
||||||
import NoteIconWidget from "../widgets/note_icon.js";
|
import NoteIconWidget from "../widgets/note_icon.js";
|
||||||
import SearchResultWidget from "../widgets/search_result.js";
|
import SearchResultWidget from "../widgets/search_result.js";
|
||||||
@ -145,6 +146,7 @@ export default class DesktopLayout {
|
|||||||
.ribbon(new NotePropertiesWidget())
|
.ribbon(new NotePropertiesWidget())
|
||||||
.ribbon(new FilePropertiesWidget())
|
.ribbon(new FilePropertiesWidget())
|
||||||
.ribbon(new ImagePropertiesWidget())
|
.ribbon(new ImagePropertiesWidget())
|
||||||
|
.ribbon(new CanvasPropertiesWidget())
|
||||||
.ribbon(new BasicPropertiesWidget())
|
.ribbon(new BasicPropertiesWidget())
|
||||||
.ribbon(new OwnedAttributeListWidget())
|
.ribbon(new OwnedAttributeListWidget())
|
||||||
.ribbon(new InheritedAttributesWidget())
|
.ribbon(new InheritedAttributesWidget())
|
||||||
|
@ -495,6 +495,14 @@ function copyHtmlToClipboard(content) {
|
|||||||
navigator.clipboard.write([clipboardItem]);
|
navigator.clipboard.write([clipboardItem]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FNote} note
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function createImageSrcUrl(note) {
|
||||||
|
return `api/images/${note.noteId}/${encodeURIComponent(note.title)}?timestamp=${Date.now()}`;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
reloadFrontendApp,
|
reloadFrontendApp,
|
||||||
parseDate,
|
parseDate,
|
||||||
@ -533,5 +541,6 @@ export default {
|
|||||||
sleep,
|
sleep,
|
||||||
escapeRegExp,
|
escapeRegExp,
|
||||||
areObjectsEqual,
|
areObjectsEqual,
|
||||||
copyHtmlToClipboard
|
copyHtmlToClipboard,
|
||||||
|
createImageSrcUrl
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ const TPL = `
|
|||||||
.global-menu-button {
|
.global-menu-button {
|
||||||
background-image: url("${window.glob.assetPath}/images/icon-black.svg");
|
background-image: url("${window.glob.assetPath}/images/icon-black.svg");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 50% 80%;
|
background-position: 40% 50%;
|
||||||
background-size: 45px;
|
background-size: 45px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -88,7 +88,7 @@ const TPL = `
|
|||||||
display: none;
|
display: none;
|
||||||
border-bottom: 1px solid var(--main-border-color);
|
border-bottom: 1px solid var(--main-border-color);
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 5px; /* needs to have this value so that the bottom border is the same width as the top one */
|
||||||
}
|
}
|
||||||
|
|
||||||
.ribbon-body.active {
|
.ribbon-body.active {
|
||||||
|
@ -16,6 +16,10 @@ const TPL = `
|
|||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.type-canvas .floating-buttons-children {
|
||||||
|
top: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
.floating-buttons-children > *:not(.hidden-int):not(.no-content-hidden) {
|
.floating-buttons-children > *:not(.hidden-int):not(.no-content-hidden) {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
@ -1147,6 +1147,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
let parentsOfAddedNodes = [];
|
let parentsOfAddedNodes = [];
|
||||||
|
|
||||||
const allBranchRows = loadResults.getBranchRows();
|
const allBranchRows = loadResults.getBranchRows();
|
||||||
|
// TODO: this flag is suspicious - why does it matter that all branches in a particular update are deleted?
|
||||||
const allBranchesDeleted = allBranchRows.every(branchRow => !!branchRow.isDeleted);
|
const allBranchesDeleted = allBranchRows.every(branchRow => !!branchRow.isDeleted);
|
||||||
|
|
||||||
for (const branchRow of allBranchRows) {
|
for (const branchRow of allBranchRows) {
|
||||||
@ -1159,8 +1160,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
noteIdsToUpdate.add(branchRow.noteId);
|
noteIdsToUpdate.add(branchRow.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const node of this.getNodesByBranch(branchRow)) {
|
|
||||||
if (branchRow.isDeleted) {
|
if (branchRow.isDeleted) {
|
||||||
|
for (const node of this.getNodesByBranch(branchRow)) {
|
||||||
if (node.isActive()) {
|
if (node.isActive()) {
|
||||||
if (allBranchesDeleted) {
|
if (allBranchesDeleted) {
|
||||||
const newActiveNode = node.getNextSibling()
|
const newActiveNode = node.getNextSibling()
|
||||||
@ -1181,9 +1182,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
noteIdsToUpdate.add(branchRow.parentNoteId);
|
noteIdsToUpdate.add(branchRow.parentNoteId);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (!branchRow.isDeleted) {
|
|
||||||
for (const parentNode of this.getNodesByNoteId(branchRow.parentNoteId)) {
|
for (const parentNode of this.getNodesByNoteId(branchRow.parentNoteId)) {
|
||||||
parentsOfAddedNodes.push(parentNode)
|
parentsOfAddedNodes.push(parentNode)
|
||||||
|
|
||||||
@ -1194,12 +1193,16 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
const found = (parentNode.getChildren() || []).find(child => child.data.noteId === branchRow.noteId);
|
const found = (parentNode.getChildren() || []).find(child => child.data.noteId === branchRow.noteId);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// make sure it's loaded
|
// make sure it's loaded
|
||||||
await froca.getNote(branchRow.noteId);
|
const note = await froca.getNote(branchRow.noteId);
|
||||||
const frocaBranch = froca.getBranch(branchRow.branchId);
|
const frocaBranch = froca.getBranch(branchRow.branchId);
|
||||||
|
|
||||||
// we're forcing lazy since it's not clear if the whole required subtree is in froca
|
// we're forcing lazy since it's not clear if the whole required subtree is in froca
|
||||||
parentNode.addChildren([this.prepareNode(frocaBranch, true)]);
|
parentNode.addChildren([this.prepareNode(frocaBranch, true)]);
|
||||||
|
|
||||||
|
if (frocaBranch.isExpanded && note.hasChildren()) {
|
||||||
|
noteIdsToReload.add(frocaBranch.noteId);
|
||||||
|
}
|
||||||
|
|
||||||
this.sortChildren(parentNode);
|
this.sortChildren(parentNode);
|
||||||
|
|
||||||
// this might be a first child which would force an icon change
|
// this might be a first child which would force an icon change
|
||||||
|
@ -17,7 +17,8 @@ const TPL = `
|
|||||||
|
|
||||||
.basic-properties-widget > * {
|
.basic-properties-widget > * {
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
margin-top: 12px;
|
margin-top: 9px;
|
||||||
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-type-container, .editability-select-container {
|
.note-type-container, .editability-select-container {
|
||||||
|
56
src/public/app/widgets/ribbon_widgets/canvas_properties.js
Normal file
56
src/public/app/widgets/ribbon_widgets/canvas_properties.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||||
|
import utils from "../../services/utils.js";
|
||||||
|
import imageService from "../../services/image.js";
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<div class="image-properties">
|
||||||
|
<div style="display: flex; justify-content: space-evenly; margin: 10px;">
|
||||||
|
<button class="canvas-copy-reference-to-clipboard btn btn-sm btn-primary"
|
||||||
|
title="Pasting this reference into a text note will insert the canvas note as image"
|
||||||
|
type="button">Copy reference to clipboard</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden-canvas-copy"></div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
export default class CanvasPropertiesWidget extends NoteContextAwareWidget {
|
||||||
|
get name() {
|
||||||
|
return "canvasProperties";
|
||||||
|
}
|
||||||
|
|
||||||
|
get toggleCommand() {
|
||||||
|
return "toggleRibbonTabCanvasProperties";
|
||||||
|
}
|
||||||
|
|
||||||
|
isEnabled() {
|
||||||
|
return this.note && this.note.type === 'canvas';
|
||||||
|
}
|
||||||
|
|
||||||
|
getTitle() {
|
||||||
|
return {
|
||||||
|
show: this.isEnabled(),
|
||||||
|
activate: false,
|
||||||
|
title: 'Canvas',
|
||||||
|
icon: 'bx bx-pen'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
this.$widget = $(TPL);
|
||||||
|
this.contentSized();
|
||||||
|
|
||||||
|
this.$hiddenCanvasCopy = this.$widget.find('.hidden-canvas-copy');
|
||||||
|
|
||||||
|
this.$copyReferenceToClipboardButton = this.$widget.find(".canvas-copy-reference-to-clipboard");
|
||||||
|
this.$copyReferenceToClipboardButton.on('click', () => {
|
||||||
|
this.$hiddenCanvasCopy.empty().append(
|
||||||
|
$("<img>")
|
||||||
|
.attr("src", utils.createImageSrcUrl(this.note))
|
||||||
|
);
|
||||||
|
|
||||||
|
imageService.copyImageReferenceToClipboard(this.$hiddenCanvasCopy);
|
||||||
|
|
||||||
|
this.$hiddenCanvasCopy.empty();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -61,9 +61,13 @@ export default class ImagePropertiesWidget extends NoteContextAwareWidget {
|
|||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.contentSized();
|
this.contentSized();
|
||||||
|
|
||||||
this.$copyReferenceToClipboardButton = this.$widget.find(".image-copy-reference-to-clipboard");
|
this.$copyReferenceToClipboardButton = this.$widget.find(".image-copy-reference-to-clipboard");
|
||||||
|
this.$copyReferenceToClipboardButton.on('click', () => this.triggerEvent(`copyImageReferenceToClipboard`, {ntxId: this.noteContext.ntxId}));
|
||||||
|
|
||||||
this.$uploadNewRevisionButton = this.$widget.find(".image-upload-new-revision");
|
this.$uploadNewRevisionButton = this.$widget.find(".image-upload-new-revision");
|
||||||
this.$uploadNewRevisionInput = this.$widget.find(".image-upload-new-revision-input");
|
this.$uploadNewRevisionInput = this.$widget.find(".image-upload-new-revision-input");
|
||||||
|
|
||||||
this.$fileName = this.$widget.find(".image-filename");
|
this.$fileName = this.$widget.find(".image-filename");
|
||||||
this.$fileType = this.$widget.find(".image-filetype");
|
this.$fileType = this.$widget.find(".image-filetype");
|
||||||
this.$fileSize = this.$widget.find(".image-filesize");
|
this.$fileSize = this.$widget.find(".image-filesize");
|
||||||
@ -74,8 +78,6 @@ export default class ImagePropertiesWidget extends NoteContextAwareWidget {
|
|||||||
this.$imageDownloadButton = this.$widget.find(".image-download");
|
this.$imageDownloadButton = this.$widget.find(".image-download");
|
||||||
this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId));
|
this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId));
|
||||||
|
|
||||||
this.$copyReferenceToClipboardButton.on('click', () => this.triggerEvent(`copyImageReferenceToClipboard`, {ntxId: this.noteContext.ntxId}));
|
|
||||||
|
|
||||||
this.$uploadNewRevisionButton.on("click", () => {
|
this.$uploadNewRevisionButton.on("click", () => {
|
||||||
this.$uploadNewRevisionInput.trigger("click");
|
this.$uploadNewRevisionInput.trigger("click");
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ const TPL = `
|
|||||||
color: var(--muted-text-color);
|
color: var(--muted-text-color);
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 12px 12px 11px 12px;
|
padding: 14px 12px 13px 12px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@ const TPL = `
|
|||||||
.attribute-list {
|
.attribute-list {
|
||||||
margin-left: 7px;
|
margin-left: 7px;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
margin-top: 3px;
|
margin-top: 5px;
|
||||||
|
margin-bottom: 2px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ const Draggabilly = window.Draggabilly;
|
|||||||
|
|
||||||
const TAB_CONTAINER_MIN_WIDTH = 24;
|
const TAB_CONTAINER_MIN_WIDTH = 24;
|
||||||
const TAB_CONTAINER_MAX_WIDTH = 240;
|
const TAB_CONTAINER_MAX_WIDTH = 240;
|
||||||
|
const TAB_CONTAINER_LEFT_PADDING = 5;
|
||||||
const NEW_TAB_WIDTH = 32;
|
const NEW_TAB_WIDTH = 32;
|
||||||
const MIN_FILLER_WIDTH = 50;
|
const MIN_FILLER_WIDTH = 50;
|
||||||
const MARGIN_WIDTH = 5;
|
const MARGIN_WIDTH = 5;
|
||||||
@ -330,7 +331,7 @@ export default class TabRowWidget extends BasicWidget {
|
|||||||
getTabPositions() {
|
getTabPositions() {
|
||||||
const tabPositions = [];
|
const tabPositions = [];
|
||||||
|
|
||||||
let position = 0;
|
let position = TAB_CONTAINER_LEFT_PADDING;
|
||||||
this.tabWidths.forEach(width => {
|
this.tabWidths.forEach(width => {
|
||||||
tabPositions.push(position);
|
tabPositions.push(position);
|
||||||
position += width + MARGIN_WIDTH;
|
position += width + MARGIN_WIDTH;
|
||||||
|
@ -90,7 +90,7 @@ class ImageTypeWidget extends TypeWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async doRefresh(note) {
|
async doRefresh(note) {
|
||||||
this.$imageView.prop("src", `api/images/${note.noteId}/${encodeURIComponent(note.title)}?timestamp=${Date.now()}`);
|
this.$imageView.prop("src", utils.createImageSrcUrl(note));
|
||||||
}
|
}
|
||||||
|
|
||||||
copyImageReferenceToClipboardEvent({ntxId}) {
|
copyImageReferenceToClipboardEvent({ntxId}) {
|
||||||
|
@ -84,11 +84,11 @@ export default class BackupOptions extends OptionsWidget {
|
|||||||
this.$existingBackupList.empty();
|
this.$existingBackupList.empty();
|
||||||
|
|
||||||
if (!backupFiles.length) {
|
if (!backupFiles.length) {
|
||||||
backupFiles = [{filePath: "no backup yet", ctime: ''}];
|
backupFiles = [{filePath: "no backup yet", mtime: ''}];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const {filePath, ctime} of backupFiles) {
|
for (const {filePath, mtime} of backupFiles) {
|
||||||
this.$existingBackupList.append($("<li>").text(`${filePath} ${ctime ? ` - ${ctime}` : ''}`));
|
this.$existingBackupList.append($("<li>").text(`${filePath} ${mtime ? ` - ${mtime}` : ''}`));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ function getExistingBackups() {
|
|||||||
const filePath = path.resolve(dataDir.BACKUP_DIR, fileName);
|
const filePath = path.resolve(dataDir.BACKUP_DIR, fileName);
|
||||||
const stat = fs.statSync(filePath)
|
const stat = fs.statSync(filePath)
|
||||||
|
|
||||||
return {fileName, filePath, ctime: stat.ctime};
|
return {fileName, filePath, mtime: stat.mtime};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2023-10-07T23:02:47+03:00", buildRevision: "3d15aeae58224ac8716dd58938458e89af9bf7a0" };
|
module.exports = { buildDate:"2023-10-19T09:33:51+02:00", buildRevision: "b01fe5ead9268784fb133a8cfa53670927ba0e3b" };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user