mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
image properties converted to collapsible section container
This commit is contained in:
parent
1ba1f28006
commit
1c51419db5
@ -18,6 +18,7 @@ import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js";
|
|||||||
import NoteListWidget from "../widgets/note_list.js";
|
import NoteListWidget from "../widgets/note_list.js";
|
||||||
import SqlResultWidget from "../widgets/sql_result.js";
|
import SqlResultWidget from "../widgets/sql_result.js";
|
||||||
import FilePropertiesWidget from "../widgets/type_property_widgets/file_properties.js";
|
import FilePropertiesWidget from "../widgets/type_property_widgets/file_properties.js";
|
||||||
|
import ImagePropertiesWidget from "../widgets/type_property_widgets/image_properties.js";
|
||||||
|
|
||||||
export default class DesktopExtraWindowLayout {
|
export default class DesktopExtraWindowLayout {
|
||||||
constructor(customWidgets) {
|
constructor(customWidgets) {
|
||||||
@ -50,6 +51,7 @@ export default class DesktopExtraWindowLayout {
|
|||||||
new TabCachingWidget(() => new CollapsibleSectionContainer()
|
new TabCachingWidget(() => new CollapsibleSectionContainer()
|
||||||
.child(new SearchDefinitionWidget())
|
.child(new SearchDefinitionWidget())
|
||||||
.child(new FilePropertiesWidget())
|
.child(new FilePropertiesWidget())
|
||||||
|
.child(new ImagePropertiesWidget())
|
||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(new OwnedAttributeListWidget())
|
.child(new OwnedAttributeListWidget())
|
||||||
.child(new InheritedAttributesWidget())
|
.child(new InheritedAttributesWidget())
|
||||||
|
@ -29,6 +29,7 @@ import Container from "../widgets/container.js";
|
|||||||
import SqlResultWidget from "../widgets/sql_result.js";
|
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/type_property_widgets/file_properties.js";
|
import FilePropertiesWidget from "../widgets/type_property_widgets/file_properties.js";
|
||||||
|
import ImagePropertiesWidget from "../widgets/type_property_widgets/image_properties.js";
|
||||||
|
|
||||||
const RIGHT_PANE_CSS = `
|
const RIGHT_PANE_CSS = `
|
||||||
<style>
|
<style>
|
||||||
@ -158,6 +159,7 @@ export default class DesktopMainWindowLayout {
|
|||||||
new TabCachingWidget(() => new CollapsibleSectionContainer()
|
new TabCachingWidget(() => new CollapsibleSectionContainer()
|
||||||
.child(new SearchDefinitionWidget())
|
.child(new SearchDefinitionWidget())
|
||||||
.child(new FilePropertiesWidget())
|
.child(new FilePropertiesWidget())
|
||||||
|
.child(new ImagePropertiesWidget())
|
||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(new OwnedAttributeListWidget())
|
.child(new OwnedAttributeListWidget())
|
||||||
.child(new InheritedAttributesWidget())
|
.child(new InheritedAttributesWidget())
|
||||||
|
111
src/public/app/widgets/type_property_widgets/image_properties.js
Normal file
111
src/public/app/widgets/type_property_widgets/image_properties.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import server from "../../services/server.js";
|
||||||
|
import TabAwareWidget from "../tab_aware_widget.js";
|
||||||
|
import toastService from "../../services/toast.js";
|
||||||
|
import openService from "../../services/open.js";
|
||||||
|
import utils from "../../services/utils.js";
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<div class="image-properties">
|
||||||
|
<div style="display: flex; justify-content: space-evenly; margin: 10px;">
|
||||||
|
<span>
|
||||||
|
<strong>Original file name:</strong>
|
||||||
|
<span class="image-filename"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<strong>File type:</strong>
|
||||||
|
<span class="image-filetype"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<strong>File size:</strong>
|
||||||
|
<span class="image-filesize"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="no-print" style="display: flex; justify-content: space-evenly; margin: 10px;">
|
||||||
|
<button class="image-download btn btn-sm btn-primary" type="button">Download</button>
|
||||||
|
|
||||||
|
<button class="image-copy-to-clipboard btn btn-sm btn-primary" type="button">Copy to clipboard</button>
|
||||||
|
|
||||||
|
<button class="image-upload-new-revision btn btn-sm btn-primary" type="button">Upload new revision</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="file" class="image-upload-new-revision-input" style="display: none">
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
export default class ImagePropertiesWidget extends TabAwareWidget {
|
||||||
|
static getType() { return "image"; }
|
||||||
|
|
||||||
|
renderTitle(note) {
|
||||||
|
return {
|
||||||
|
show: note.type === 'image',
|
||||||
|
activate: true,
|
||||||
|
$title: 'Image'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
this.$widget = $(TPL);
|
||||||
|
this.contentSized();
|
||||||
|
this.$copyToClipboardButton = this.$widget.find(".image-copy-to-clipboard");
|
||||||
|
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");
|
||||||
|
|
||||||
|
this.$imageDownloadButton = this.$widget.find(".image-download");
|
||||||
|
this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId));
|
||||||
|
|
||||||
|
this.$copyToClipboardButton.on('click', () => this.triggerEvent(`copyImageToClipboard`, {tabId: this.tabContext.tabId}));
|
||||||
|
|
||||||
|
this.$uploadNewRevisionButton.on("click", () => {
|
||||||
|
this.$uploadNewRevisionInput.trigger("click");
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$uploadNewRevisionInput.on('change', async () => {
|
||||||
|
const fileToUpload = this.$uploadNewRevisionInput[0].files[0]; // copy to allow reset below
|
||||||
|
this.$uploadNewRevisionInput.val('');
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('upload', fileToUpload);
|
||||||
|
|
||||||
|
const result = await $.ajax({
|
||||||
|
url: baseApiUrl + 'images/' + this.noteId,
|
||||||
|
headers: await server.getHeaders(),
|
||||||
|
data: formData,
|
||||||
|
type: 'PUT',
|
||||||
|
timeout: 60 * 60 * 1000,
|
||||||
|
contentType: false, // NEEDED, DON'T REMOVE THIS
|
||||||
|
processData: false, // NEEDED, DON'T REMOVE THIS
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.uploaded) {
|
||||||
|
toastService.showMessage("New image revision has been uploaded.");
|
||||||
|
|
||||||
|
await utils.clearBrowserCache();
|
||||||
|
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toastService.showError("Upload of a new image revision failed: " + result.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async refreshWithNote(note) {
|
||||||
|
const attributes = note.getAttributes();
|
||||||
|
const attributeMap = utils.toObject(attributes, l => [l.name, l.value]);
|
||||||
|
|
||||||
|
this.$widget.show();
|
||||||
|
|
||||||
|
const noteComplement = await this.tabContext.getNoteComplement();
|
||||||
|
|
||||||
|
this.$fileName.text(attributeMap.originalFileName || "?");
|
||||||
|
this.$fileSize.text(noteComplement.contentLength + " bytes");
|
||||||
|
this.$fileType.text(note.mime);
|
||||||
|
|
||||||
|
const imageHash = utils.randomString(10);
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
import toastService from "../../services/toast.js";
|
import toastService from "../../services/toast.js";
|
||||||
import server from "../../services/server.js";
|
|
||||||
import openService from "../../services/open.js";
|
|
||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-image note-detail-printable">
|
<div class="note-detail-image note-detail-printable">
|
||||||
<style>
|
<style>
|
||||||
|
.type-image {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.note-detail-image {
|
.note-detail-image {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -18,36 +20,9 @@ const TPL = `
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="no-print" style="display: flex; justify-content: space-evenly; margin: 10px;">
|
|
||||||
<button class="image-download btn btn-sm btn-primary" type="button">Download</button>
|
|
||||||
|
|
||||||
<button class="image-copy-to-clipboard btn btn-sm btn-primary" type="button">Copy to clipboard</button>
|
|
||||||
|
|
||||||
<button class="image-upload-new-revision btn btn-sm btn-primary" type="button">Upload new revision</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="note-detail-image-wrapper">
|
<div class="note-detail-image-wrapper">
|
||||||
<img class="note-detail-image-view" />
|
<img class="note-detail-image-view" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display: flex; justify-content: space-evenly; margin: 10px;">
|
|
||||||
<span>
|
|
||||||
<strong>Original file name:</strong>
|
|
||||||
<span class="image-filename"></span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<strong>File type:</strong>
|
|
||||||
<span class="image-filetype"></span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<strong>File size:</strong>
|
|
||||||
<span class="image-filesize"></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="file" class="image-upload-new-revision-input" style="display: none">
|
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
class ImageTypeWidget extends TypeWidget {
|
class ImageTypeWidget extends TypeWidget {
|
||||||
@ -58,17 +33,19 @@ class ImageTypeWidget extends TypeWidget {
|
|||||||
this.contentSized();
|
this.contentSized();
|
||||||
this.$imageWrapper = this.$widget.find('.note-detail-image-wrapper');
|
this.$imageWrapper = this.$widget.find('.note-detail-image-wrapper');
|
||||||
this.$imageView = this.$widget.find('.note-detail-image-view');
|
this.$imageView = this.$widget.find('.note-detail-image-view');
|
||||||
this.$copyToClipboardButton = this.$widget.find(".image-copy-to-clipboard");
|
}
|
||||||
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");
|
|
||||||
|
|
||||||
this.$imageDownloadButton = this.$widget.find(".image-download");
|
async doRefresh(note) {
|
||||||
this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId));
|
const imageHash = utils.randomString(10);
|
||||||
|
|
||||||
|
this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}?${imageHash}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
copyImageToClipboardEvent({tabId}) {
|
||||||
|
if (!this.isTab(tabId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.$copyToClipboardButton.on('click',() => {
|
|
||||||
this.$imageWrapper.attr('contenteditable','true');
|
this.$imageWrapper.attr('contenteditable','true');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -87,57 +64,6 @@ class ImageTypeWidget extends TypeWidget {
|
|||||||
window.getSelection().removeAllRanges();
|
window.getSelection().removeAllRanges();
|
||||||
this.$imageWrapper.removeAttr('contenteditable');
|
this.$imageWrapper.removeAttr('contenteditable');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
this.$uploadNewRevisionButton.on("click", () => {
|
|
||||||
this.$uploadNewRevisionInput.trigger("click");
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$uploadNewRevisionInput.on('change', async () => {
|
|
||||||
const fileToUpload = this.$uploadNewRevisionInput[0].files[0]; // copy to allow reset below
|
|
||||||
this.$uploadNewRevisionInput.val('');
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('upload', fileToUpload);
|
|
||||||
|
|
||||||
const result = await $.ajax({
|
|
||||||
url: baseApiUrl + 'images/' + this.noteId,
|
|
||||||
headers: await server.getHeaders(),
|
|
||||||
data: formData,
|
|
||||||
type: 'PUT',
|
|
||||||
timeout: 60 * 60 * 1000,
|
|
||||||
contentType: false, // NEEDED, DON'T REMOVE THIS
|
|
||||||
processData: false, // NEEDED, DON'T REMOVE THIS
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.uploaded) {
|
|
||||||
toastService.showMessage("New image revision has been uploaded.");
|
|
||||||
|
|
||||||
await utils.clearBrowserCache();
|
|
||||||
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
toastService.showError("Upload of a new image revision failed: " + result.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async doRefresh(note) {
|
|
||||||
const attributes = note.getAttributes();
|
|
||||||
const attributeMap = utils.toObject(attributes, l => [l.name, l.value]);
|
|
||||||
|
|
||||||
this.$widget.show();
|
|
||||||
|
|
||||||
const noteComplement = await this.tabContext.getNoteComplement();
|
|
||||||
|
|
||||||
this.$fileName.text(attributeMap.originalFileName || "?");
|
|
||||||
this.$fileSize.text(noteComplement.contentLength + " bytes");
|
|
||||||
this.$fileType.text(note.mime);
|
|
||||||
|
|
||||||
const imageHash = utils.randomString(10);
|
|
||||||
|
|
||||||
this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}?${imageHash}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectImage(element) {
|
selectImage(element) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user