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 FilePropertiesWidget from "../widgets/ribbon_widgets/file_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 NoteIconWidget from "../widgets/note_icon.js";
|
||||
import SearchResultWidget from "../widgets/search_result.js";
|
||||
@ -145,6 +146,7 @@ export default class DesktopLayout {
|
||||
.ribbon(new NotePropertiesWidget())
|
||||
.ribbon(new FilePropertiesWidget())
|
||||
.ribbon(new ImagePropertiesWidget())
|
||||
.ribbon(new CanvasPropertiesWidget())
|
||||
.ribbon(new BasicPropertiesWidget())
|
||||
.ribbon(new OwnedAttributeListWidget())
|
||||
.ribbon(new InheritedAttributesWidget())
|
||||
|
@ -495,6 +495,14 @@ function copyHtmlToClipboard(content) {
|
||||
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 {
|
||||
reloadFrontendApp,
|
||||
parseDate,
|
||||
@ -533,5 +541,6 @@ export default {
|
||||
sleep,
|
||||
escapeRegExp,
|
||||
areObjectsEqual,
|
||||
copyHtmlToClipboard
|
||||
copyHtmlToClipboard,
|
||||
createImageSrcUrl
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ const TPL = `
|
||||
.global-menu-button {
|
||||
background-image: url("${window.glob.assetPath}/images/icon-black.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 80%;
|
||||
background-position: 40% 50%;
|
||||
background-size: 45px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -88,7 +88,7 @@ const TPL = `
|
||||
display: none;
|
||||
border-bottom: 1px solid var(--main-border-color);
|
||||
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 {
|
||||
|
@ -16,6 +16,10 @@ const TPL = `
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.type-canvas .floating-buttons-children {
|
||||
top: 70px;
|
||||
}
|
||||
|
||||
.floating-buttons-children > *:not(.hidden-int):not(.no-content-hidden) {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
@ -1147,6 +1147,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
let parentsOfAddedNodes = [];
|
||||
|
||||
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);
|
||||
|
||||
for (const branchRow of allBranchRows) {
|
||||
@ -1159,8 +1160,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
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 (allBranchesDeleted) {
|
||||
const newActiveNode = node.getNextSibling()
|
||||
@ -1181,9 +1182,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
noteIdsToUpdate.add(branchRow.parentNoteId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!branchRow.isDeleted) {
|
||||
} else {
|
||||
for (const parentNode of this.getNodesByNoteId(branchRow.parentNoteId)) {
|
||||
parentsOfAddedNodes.push(parentNode)
|
||||
|
||||
@ -1194,12 +1193,16 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const found = (parentNode.getChildren() || []).find(child => child.data.noteId === branchRow.noteId);
|
||||
if (!found) {
|
||||
// make sure it's loaded
|
||||
await froca.getNote(branchRow.noteId);
|
||||
const note = await froca.getNote(branchRow.noteId);
|
||||
const frocaBranch = froca.getBranch(branchRow.branchId);
|
||||
|
||||
// we're forcing lazy since it's not clear if the whole required subtree is in froca
|
||||
parentNode.addChildren([this.prepareNode(frocaBranch, true)]);
|
||||
|
||||
if (frocaBranch.isExpanded && note.hasChildren()) {
|
||||
noteIdsToReload.add(frocaBranch.noteId);
|
||||
}
|
||||
|
||||
this.sortChildren(parentNode);
|
||||
|
||||
// this might be a first child which would force an icon change
|
||||
|
@ -17,7 +17,8 @@ const TPL = `
|
||||
|
||||
.basic-properties-widget > * {
|
||||
margin-right: 30px;
|
||||
margin-top: 12px;
|
||||
margin-top: 9px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.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() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
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.$uploadNewRevisionInput = this.$widget.find(".image-upload-new-revision-input");
|
||||
|
||||
this.$fileName = this.$widget.find(".image-filename");
|
||||
this.$fileType = this.$widget.find(".image-filetype");
|
||||
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.on('click', () => openService.downloadFileNote(this.noteId));
|
||||
|
||||
this.$copyReferenceToClipboardButton.on('click', () => this.triggerEvent(`copyImageReferenceToClipboard`, {ntxId: this.noteContext.ntxId}));
|
||||
|
||||
this.$uploadNewRevisionButton.on("click", () => {
|
||||
this.$uploadNewRevisionInput.trigger("click");
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ const TPL = `
|
||||
color: var(--muted-text-color);
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
padding: 12px 12px 11px 12px;
|
||||
padding: 14px 12px 13px 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -8,7 +8,8 @@ const TPL = `
|
||||
.attribute-list {
|
||||
margin-left: 7px;
|
||||
margin-right: 7px;
|
||||
margin-top: 3px;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ const Draggabilly = window.Draggabilly;
|
||||
|
||||
const TAB_CONTAINER_MIN_WIDTH = 24;
|
||||
const TAB_CONTAINER_MAX_WIDTH = 240;
|
||||
const TAB_CONTAINER_LEFT_PADDING = 5;
|
||||
const NEW_TAB_WIDTH = 32;
|
||||
const MIN_FILLER_WIDTH = 50;
|
||||
const MARGIN_WIDTH = 5;
|
||||
@ -330,7 +331,7 @@ export default class TabRowWidget extends BasicWidget {
|
||||
getTabPositions() {
|
||||
const tabPositions = [];
|
||||
|
||||
let position = 0;
|
||||
let position = TAB_CONTAINER_LEFT_PADDING;
|
||||
this.tabWidths.forEach(width => {
|
||||
tabPositions.push(position);
|
||||
position += width + MARGIN_WIDTH;
|
||||
|
@ -90,7 +90,7 @@ class ImageTypeWidget extends TypeWidget {
|
||||
}
|
||||
|
||||
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}) {
|
||||
|
@ -84,11 +84,11 @@ export default class BackupOptions extends OptionsWidget {
|
||||
this.$existingBackupList.empty();
|
||||
|
||||
if (!backupFiles.length) {
|
||||
backupFiles = [{filePath: "no backup yet", ctime: ''}];
|
||||
backupFiles = [{filePath: "no backup yet", mtime: ''}];
|
||||
}
|
||||
|
||||
for (const {filePath, ctime} of backupFiles) {
|
||||
this.$existingBackupList.append($("<li>").text(`${filePath} ${ctime ? ` - ${ctime}` : ''}`));
|
||||
for (const {filePath, mtime} of backupFiles) {
|
||||
this.$existingBackupList.append($("<li>").text(`${filePath} ${mtime ? ` - ${mtime}` : ''}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ function getExistingBackups() {
|
||||
const filePath = path.resolve(dataDir.BACKUP_DIR, fileName);
|
||||
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