note image detail

This commit is contained in:
azivner 2018-11-08 10:30:35 +01:00
parent d0d2a7fe47
commit 21e952a7f0
13 changed files with 39 additions and 67 deletions

View File

@ -13,6 +13,7 @@ import NoteFull from "../entities/note_full.js";
import noteDetailCode from './note_detail_code.js'; import noteDetailCode from './note_detail_code.js';
import noteDetailText from './note_detail_text.js'; import noteDetailText from './note_detail_text.js';
import noteDetailFile from './note_detail_file.js'; import noteDetailFile from './note_detail_file.js';
import noteDetailImage from './note_detail_image.js';
import noteDetailSearch from './note_detail_search.js'; import noteDetailSearch from './note_detail_search.js';
import noteDetailRender from './note_detail_render.js'; import noteDetailRender from './note_detail_render.js';
import noteDetailRelationMap from './note_detail_relation_map.js'; import noteDetailRelationMap from './note_detail_relation_map.js';
@ -45,6 +46,7 @@ const components = {
'code': noteDetailCode, 'code': noteDetailCode,
'text': noteDetailText, 'text': noteDetailText,
'file': noteDetailFile, 'file': noteDetailFile,
'image': noteDetailImage,
'search': noteDetailSearch, 'search': noteDetailSearch,
'render': noteDetailRender, 'render': noteDetailRender,
'relation-map': noteDetailRelationMap 'relation-map': noteDetailRelationMap

View File

@ -6,7 +6,7 @@ import noteDetailService from "./note_detail.js";
let codeEditor = null; let codeEditor = null;
const $noteDetailCode = $('#note-detail-code'); const $component = $('#note-detail-code');
const $executeScriptButton = $("#execute-script-button"); const $executeScriptButton = $("#execute-script-button");
async function show() { async function show() {
@ -22,7 +22,7 @@ async function show() {
CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js';
codeEditor = CodeMirror($noteDetailCode[0], { codeEditor = CodeMirror($component[0], {
value: "", value: "",
viewportMargin: Infinity, viewportMargin: Infinity,
indentUnit: 4, indentUnit: 4,
@ -38,7 +38,7 @@ async function show() {
onNoteChange(noteDetailService.noteChanged); onNoteChange(noteDetailService.noteChanged);
} }
$noteDetailCode.show(); $component.show();
const currentNote = noteDetailService.getCurrentNote(); const currentNote = noteDetailService.getCurrentNote();

View File

@ -3,7 +3,7 @@ import server from "./server.js";
import protectedSessionHolder from "./protected_session_holder.js"; import protectedSessionHolder from "./protected_session_holder.js";
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
const $noteDetailFile = $('#note-detail-file'); const $component = $('#note-detail-file');
const $fileFileName = $("#file-filename"); const $fileFileName = $("#file-filename");
const $fileFileType = $("#file-filetype"); const $fileFileType = $("#file-filetype");
@ -17,7 +17,7 @@ async function show() {
const attributes = await server.get('notes/' + currentNote.noteId + '/attributes'); const attributes = await server.get('notes/' + currentNote.noteId + '/attributes');
const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); const attributeMap = utils.toObject(attributes, l => [l.name, l.value]);
$noteDetailFile.show(); $component.show();
$fileFileName.text(attributeMap.originalFileName); $fileFileName.text(attributeMap.originalFileName);
$fileFileSize.text(attributeMap.fileSize + " bytes"); $fileFileSize.text(attributeMap.fileSize + " bytes");

View File

@ -3,39 +3,20 @@ import server from "./server.js";
import protectedSessionHolder from "./protected_session_holder.js"; import protectedSessionHolder from "./protected_session_holder.js";
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
const $noteDetailFile = $('#note-detail-file'); const $component = $('#note-detail-image');
const $imageView = $('#note-detail-image-view');
const $fileFileName = $("#file-filename"); const $imageDownload = $("#image-download");
const $fileFileType = $("#file-filetype");
const $fileFileSize = $("#file-filesize");
const $fileDownload = $("#file-download");
const $fileOpen = $("#file-open");
async function show() { async function show() {
const currentNote = noteDetailService.getCurrentNote(); const currentNote = noteDetailService.getCurrentNote();
const attributes = await server.get('notes/' + currentNote.noteId + '/attributes'); $component.show();
const attributeMap = utils.toObject(attributes, l => [l.name, l.value]);
$noteDetailFile.show(); $imageView.prop("src", `/api/images/${currentNote.noteId}/${currentNote.title}`);
$fileFileName.text(attributeMap.originalFileName);
$fileFileSize.text(attributeMap.fileSize + " bytes");
$fileFileType.text(currentNote.mime);
} }
$fileDownload.click(() => utils.download(getFileUrl())); $imageDownload.click(() => utils.download(getFileUrl()));
$fileOpen.click(() => {
if (utils.isElectron()) {
const open = require("open");
open(getFileUrl());
}
else {
window.location.href = getFileUrl();
}
});
function getFileUrl() { function getFileUrl() {
// electron needs absolute URL so we extract current host, port, protocol // electron needs absolute URL so we extract current host, port, protocol

View File

@ -4,7 +4,7 @@ import linkService from "./link.js";
import libraryLoader from "./library_loader.js"; import libraryLoader from "./library_loader.js";
import treeService from "./tree.js"; import treeService from "./tree.js";
const $noteDetailRelationMap = $("#note-detail-relation-map"); const $component = $("#note-detail-relation-map");
const $relationMapCanvas = $("#relation-map-canvas"); const $relationMapCanvas = $("#relation-map-canvas");
const $addChildNotesButton = $("#relation-map-add-child-notes"); const $addChildNotesButton = $("#relation-map-add-child-notes");
const $createChildNote = $("#relation-map-create-child-note"); const $createChildNote = $("#relation-map-create-child-note");
@ -60,7 +60,7 @@ function loadMapData() {
} }
async function show() { async function show() {
$noteDetailRelationMap.show(); $component.show();
await libraryLoader.requireLibrary(libraryLoader.RELATION_MAP); await libraryLoader.requireLibrary(libraryLoader.RELATION_MAP);

View File

@ -2,7 +2,7 @@ import bundleService from "./bundle.js";
import server from "./server.js"; import server from "./server.js";
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
const $noteDetailRender = $('#note-detail-render'); const $component = $('#note-detail-render');
const $noteDetailRenderHelp = $('#note-detail-render-help'); const $noteDetailRenderHelp = $('#note-detail-render-help');
const $noteDetailRenderContent = $('#note-detail-render-content'); const $noteDetailRenderContent = $('#note-detail-render-content');
const $renderButton = $('#render-button'); const $renderButton = $('#render-button');
@ -14,7 +14,7 @@ async function render() {
&& attr.name === 'renderNote' && attr.name === 'renderNote'
&& !!attr.value); && !!attr.value);
$noteDetailRender.show(); $component.show();
$noteDetailRenderContent.empty(); $noteDetailRenderContent.empty();
$noteDetailRenderContent.toggle(renderNotes.length > 0); $noteDetailRenderContent.toggle(renderNotes.length > 0);

View File

@ -1,7 +1,7 @@
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
const $searchString = $("#search-string"); const $searchString = $("#search-string");
const $noteDetailSearch = $('#note-detail-search'); const $component = $('#note-detail-search');
function getContent() { function getContent() {
JSON.stringify({ JSON.stringify({
@ -10,7 +10,7 @@ function getContent() {
} }
function show() { function show() {
$noteDetailSearch.show(); $component.show();
try { try {
const json = JSON.parse(noteDetailService.getCurrentNote().content); const json = JSON.parse(noteDetailService.getCurrentNote().content);

View File

@ -3,7 +3,7 @@ import noteDetailService from './note_detail.js';
import utils from "./utils.js"; import utils from "./utils.js";
import infoService from "./info.js"; import infoService from "./info.js";
const $noteDetailText = $('#note-detail-text'); const $component = $('#note-detail-text');
const $markdownImportDialog = $('#markdown-import-dialog'); const $markdownImportDialog = $('#markdown-import-dialog');
const $markdownImportTextarea = $('#markdown-import-textarea'); const $markdownImportTextarea = $('#markdown-import-textarea');
@ -18,7 +18,7 @@ async function show() {
// textEditor might have been initialized during previous await so checking again // textEditor might have been initialized during previous await so checking again
// looks like double initialization can freeze CKEditor pretty badly // looks like double initialization can freeze CKEditor pretty badly
if (!textEditor) { if (!textEditor) {
textEditor = await BalloonEditor.create($noteDetailText[0]); textEditor = await BalloonEditor.create($component[0]);
onNoteChange(noteDetailService.noteChanged); onNoteChange(noteDetailService.noteChanged);
} }
@ -26,7 +26,7 @@ async function show() {
textEditor.setData(noteDetailService.getCurrentNote().content); textEditor.setData(noteDetailService.getCurrentNote().content);
$noteDetailText.show(); $component.show();
} }
function getContent() { function getContent() {
@ -42,7 +42,7 @@ function getContent() {
} }
function focus() { function focus() {
$noteDetailText.focus(); $component.focus();
} }
function getEditor() { function getEditor() {

View File

@ -6,19 +6,22 @@ const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
const fs = require('fs'); const fs = require('fs');
async function returnImage(req, res) { async function returnImage(req, res) {
const image = await repository.getImage(req.params.imageId); const image = await repository.getNote(req.params.noteId);
if (!image) { if (!image) {
return res.sendStatus(404); return res.sendStatus(404);
} }
else if (image.type !== 'image') {
return res.sendStatus(400);
}
else if (image.data === null) { else if (image.data === null) {
res.set('Content-Type', 'image/png'); res.set('Content-Type', 'image/png');
return res.send(fs.readFileSync(RESOURCE_DIR + '/db/image-deleted.png')); return res.send(fs.readFileSync(RESOURCE_DIR + '/db/image-deleted.png'));
} }
res.set('Content-Type', 'image/' + image.format); res.set('Content-Type', image.mime);
res.send(image.data); res.send(image.content);
} }
async function uploadImage(req) { async function uploadImage(req) {

View File

@ -144,7 +144,7 @@ function register(app) {
apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames); apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames);
apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute); apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute);
route(GET, '/api/images/:imageId/:filename', [auth.checkApiAuthOrElectron], imageRoute.returnImage); route(GET, '/api/images/:noteId/:filename', [auth.checkApiAuthOrElectron], imageRoute.returnImage);
route(POST, '/api/images', [auth.checkApiAuthOrElectron, uploadMiddleware], imageRoute.uploadImage, apiResultHandler); route(POST, '/api/images', [auth.checkApiAuthOrElectron, uploadMiddleware], imageRoute.uploadImage, apiResultHandler);
apiRoute(GET, '/api/recent-changes', recentChangesApiRoute.getRecentChanges); apiRoute(GET, '/api/recent-changes', recentChangesApiRoute.getRecentChanges);

View File

@ -182,27 +182,6 @@ async function runAllChecks() {
COUNT(*) > 1`, COUNT(*) > 1`,
"Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList); "Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList);
await runCheck(`
SELECT
images.imageId
FROM
images
LEFT JOIN note_images ON note_images.imageId = images.imageId
WHERE
note_images.noteImageId IS NULL`,
"Image with no note relation", errorList);
await runCheck(`
SELECT
note_images.noteImageId
FROM
note_images
JOIN images USING(imageId)
WHERE
note_images.isDeleted = 0
AND images.isDeleted = 1`,
"Note image is not deleted while image is deleted for noteImageId", errorList);
await runCheck(` await runCheck(`
SELECT SELECT
noteId noteId
@ -232,8 +211,6 @@ async function runAllChecks() {
await runSyncRowChecks("note_revisions", "noteRevisionId", errorList); await runSyncRowChecks("note_revisions", "noteRevisionId", errorList);
await runSyncRowChecks("branches", "branchId", errorList); await runSyncRowChecks("branches", "branchId", errorList);
await runSyncRowChecks("recent_notes", "branchId", errorList); await runSyncRowChecks("recent_notes", "branchId", errorList);
await runSyncRowChecks("images", "imageId", errorList);
await runSyncRowChecks("note_images", "noteImageId", errorList);
await runSyncRowChecks("attributes", "attributeId", errorList); await runSyncRowChecks("attributes", "attributeId", errorList);
await runSyncRowChecks("api_tokens", "apiTokenId", errorList); await runSyncRowChecks("api_tokens", "apiTokenId", errorList);
await runSyncRowChecks("options", "name", errorList); await runSyncRowChecks("options", "name", errorList);

View File

@ -15,6 +15,8 @@
<% include file.ejs %> <% include file.ejs %>
<% include image.ejs %>
<% include relation_map.ejs %> <% include relation_map.ejs %>
</div> </div>

View File

@ -0,0 +1,7 @@
<div id="note-detail-image" class="note-detail-component">
<img id="note-detail-image-view" />
<br/>
<br/>
<button id="file-download" class="btn btn-primary" type="button">Download</button>
</div>