mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
note tooltip displays the whole note with scrollbar, other behavior changes. closes #4120
This commit is contained in:
parent
d0e5ad5b7e
commit
ddf75cd5e5
@ -182,8 +182,6 @@ export default class Entrypoints extends Component {
|
||||
}
|
||||
|
||||
hideAllPopups() {
|
||||
$(".tooltip").removeClass("show");
|
||||
|
||||
if (utils.isDesktop()) {
|
||||
$(".aa-input").autocomplete("close");
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
class FAttachment {
|
||||
constructor(froca, row) {
|
||||
/** @type {Froca} */
|
||||
this.froca = froca;
|
||||
|
||||
this.update(row);
|
||||
@ -34,12 +35,9 @@ class FAttachment {
|
||||
return this.froca.notes[this.ownerId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [opts.preview=false] - retrieve only first 10 000 characters for a preview
|
||||
* @return {FBlob}
|
||||
*/
|
||||
async getBlob(opts = {}) {
|
||||
return await this.froca.getBlob('attachments', this.attachmentId, opts);
|
||||
/** @return {FBlob} */
|
||||
async getBlob() {
|
||||
return await this.froca.getBlob('attachments', this.attachmentId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import promotedAttributeDefinitionParser from '../services/promoted_attribute_de
|
||||
*/
|
||||
class FAttribute {
|
||||
constructor(froca, row) {
|
||||
/** @type {Froca} */
|
||||
this.froca = froca;
|
||||
|
||||
this.update(row);
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
class FBranch {
|
||||
constructor(froca, row) {
|
||||
/** @type {Froca} */
|
||||
this.froca = froca;
|
||||
|
||||
this.update(row);
|
||||
|
@ -31,6 +31,7 @@ class FNote {
|
||||
* @param {Object.<string, Object>} row
|
||||
*/
|
||||
constructor(froca, row) {
|
||||
/** @type {Froca} */
|
||||
this.froca = froca;
|
||||
|
||||
/** @type {string[]} */
|
||||
@ -859,12 +860,9 @@ class FNote {
|
||||
return this.getBlob();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [opts.preview=false] - retrieve only first 10 000 characters for a preview
|
||||
* @return {Promise<FBlob>}
|
||||
*/
|
||||
async getBlob(opts = {}) {
|
||||
return await this.froca.getBlob('notes', this.noteId, opts);
|
||||
/** @return {Promise<FBlob>} */
|
||||
async getBlob() {
|
||||
return await this.froca.getBlob('notes', this.noteId);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
@ -19,7 +19,6 @@ let idCounter = 1;
|
||||
*/
|
||||
async function getRenderedContent(entity, options = {}) {
|
||||
options = Object.assign({
|
||||
trim: false,
|
||||
tooltip: false
|
||||
}, options);
|
||||
|
||||
@ -29,7 +28,7 @@ async function getRenderedContent(entity, options = {}) {
|
||||
const $renderedContent = $('<div class="rendered-content">');
|
||||
|
||||
if (type === 'text') {
|
||||
await renderText(entity, options, $renderedContent);
|
||||
await renderText(entity, $renderedContent);
|
||||
}
|
||||
else if (type === 'code') {
|
||||
await renderCode(entity, options, $renderedContent);
|
||||
@ -86,12 +85,13 @@ async function getRenderedContent(entity, options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
async function renderText(note, options, $renderedContent) {
|
||||
/** @param {FNote} note */
|
||||
async function renderText(note, $renderedContent) {
|
||||
// entity must be FNote
|
||||
const blob = await note.getBlob({preview: options.trim});
|
||||
const blob = await note.getBlob();
|
||||
|
||||
if (!utils.isHtmlEmpty(blob.content)) {
|
||||
$renderedContent.append($('<div class="ck-content">').html(trim(blob.content, options.trim)));
|
||||
$renderedContent.append($('<div class="ck-content">').html(blob.content));
|
||||
|
||||
if ($renderedContent.find('span.math-tex').length > 0) {
|
||||
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
||||
@ -112,10 +112,11 @@ async function renderText(note, options, $renderedContent) {
|
||||
}
|
||||
}
|
||||
|
||||
async function renderCode(note, options, $renderedContent) {
|
||||
const blob = await note.getBlob({preview: options.trim});
|
||||
/** @param {FNote} note */
|
||||
async function renderCode(note, $renderedContent) {
|
||||
const blob = await note.getBlob();
|
||||
|
||||
$renderedContent.append($("<pre>").text(trim(blob.content, options.trim)));
|
||||
$renderedContent.append($("<pre>").text(blob.content));
|
||||
}
|
||||
|
||||
function renderImage(entity, $renderedContent, options = {}) {
|
||||
@ -285,15 +286,6 @@ async function renderChildrenList($renderedContent, note) {
|
||||
}
|
||||
}
|
||||
|
||||
function trim(text, doTrim) {
|
||||
if (!doTrim) {
|
||||
return text;
|
||||
}
|
||||
else {
|
||||
return text.substr(0, Math.min(text.length, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
function getRenderingType(entity) {
|
||||
let type = entity.type || entity.role;
|
||||
const mime = entity.mime;
|
||||
|
@ -368,12 +368,11 @@ class Froca {
|
||||
}
|
||||
|
||||
/** @returns {Promise<FBlob>} */
|
||||
async getBlob(entityType, entityId, opts = {}) {
|
||||
opts.preview = !!opts.preview;
|
||||
const key = `${entityType}-${entityId}-${opts.preview}`;
|
||||
async getBlob(entityType, entityId) {
|
||||
const key = `${entityType}-${entityId}`;
|
||||
|
||||
if (!this.blobPromises[key]) {
|
||||
this.blobPromises[key] = server.get(`${entityType}/${entityId}/blob?preview=${opts.preview}`)
|
||||
this.blobPromises[key] = server.get(`${entityType}/${entityId}/blob`)
|
||||
.then(row => new FBlob(row))
|
||||
.catch(e => console.error(`Cannot get blob for ${entityType} '${entityId}'`));
|
||||
|
||||
|
@ -8,27 +8,32 @@ import appContext from "../components/app_context.js";
|
||||
|
||||
function setupGlobalTooltip() {
|
||||
$(document).on("mouseenter", "a", mouseEnterHandler);
|
||||
$(document).on("mouseleave", "a", mouseLeaveHandler);
|
||||
|
||||
// close any note tooltip after click, this fixes the problem that sometimes tooltips remained on the screen
|
||||
$(document).on("click", () => $('.note-tooltip').remove());
|
||||
$(document).on("click", e => {
|
||||
if ($(e.target).closest(".note-tooltip").length) {
|
||||
// click within the tooltip shouldn't close it
|
||||
return;
|
||||
}
|
||||
|
||||
$('.note-tooltip').remove();
|
||||
});
|
||||
}
|
||||
|
||||
function setupElementTooltip($el) {
|
||||
$el.on('mouseenter', mouseEnterHandler);
|
||||
$el.on('mouseleave', mouseLeaveHandler);
|
||||
}
|
||||
|
||||
async function mouseEnterHandler() {
|
||||
const $link = $(this);
|
||||
|
||||
if ($link.hasClass("no-tooltip-preview")
|
||||
|| $link.hasClass("disabled")) {
|
||||
if ($link.hasClass("no-tooltip-preview") || $link.hasClass("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this is to avoid showing tooltip from inside the CKEditor link editor dialog
|
||||
if ($link.closest(".ck-link-actions").length) {
|
||||
} else if ($link.closest(".ck-link-actions").length) {
|
||||
// this is to avoid showing tooltip from inside the CKEditor link editor dialog
|
||||
return;
|
||||
} else if ($link.closest(".note-tooltip").length) {
|
||||
// don't show tooltip for links within tooltip
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,8 +44,21 @@ async function mouseEnterHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
const linkId = $link.attr("data-link-id") || `link-${Math.floor(Math.random() * 1000000)}`;
|
||||
$link.attr("data-link-id", linkId);
|
||||
|
||||
if ($(`.${linkId}`).is(":visible")) {
|
||||
// tooltip is already open for this link
|
||||
return;
|
||||
}
|
||||
|
||||
const note = await froca.getNote(noteId);
|
||||
const content = await renderTooltip(note);
|
||||
|
||||
const [content] = await Promise.all([
|
||||
renderTooltip(note),
|
||||
// to reduce flicker due to accidental mouseover, cursor must stay for a bit over the link for tooltip to appear
|
||||
new Promise(res => setTimeout(res, 500))
|
||||
]);
|
||||
|
||||
if (utils.isHtmlEmpty(content)) {
|
||||
return;
|
||||
@ -53,7 +71,6 @@ async function mouseEnterHandler() {
|
||||
// we now create tooltip which won't close because it won't receive mouseleave event
|
||||
if ($(this).is(":hover")) {
|
||||
$(this).tooltip({
|
||||
delay: {"show": 300, "hide": 100},
|
||||
container: 'body',
|
||||
// https://github.com/zadam/trilium/issues/2794 https://github.com/zadam/trilium/issues/2988
|
||||
// with bottom this flickering happens a bit less
|
||||
@ -63,15 +80,19 @@ async function mouseEnterHandler() {
|
||||
title: html,
|
||||
html: true,
|
||||
template: '<div class="tooltip note-tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',
|
||||
sanitize: false
|
||||
sanitize: false,
|
||||
customClass: linkId
|
||||
});
|
||||
|
||||
$(this).tooltip('show');
|
||||
}
|
||||
}
|
||||
|
||||
function mouseLeaveHandler() {
|
||||
$(this).tooltip('dispose');
|
||||
setTimeout(() => {
|
||||
if (!$(this).is(":hover") && !$(`.${linkId}`).is(":hover")) {
|
||||
// cursor is neither over the link nor over the tooltip, user likely is not interested
|
||||
$(this).tooltip('dispose');
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
async function renderTooltip(note) {
|
||||
|
@ -471,7 +471,7 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
.note-tooltip-content {
|
||||
/* height needs to stay small because tooltip has problem when it can't fit to either top or bottom of the cursor */
|
||||
max-height: 300px;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.note-tooltip-content .note-title-with-path .note-path {
|
||||
|
@ -15,9 +15,7 @@ function getNote(req) {
|
||||
}
|
||||
|
||||
function getNoteBlob(req) {
|
||||
const preview = req.query.preview === 'true';
|
||||
|
||||
return blobService.getBlobPojo('notes', req.params.noteId, { preview });
|
||||
return blobService.getBlobPojo('notes', req.params.noteId);
|
||||
}
|
||||
|
||||
function getNoteMetadata(req) {
|
||||
|
@ -2,9 +2,7 @@ const becca = require('../becca/becca');
|
||||
const NotFoundError = require("../errors/not_found_error");
|
||||
const protectedSessionService = require("./protected_session");
|
||||
|
||||
function getBlobPojo(entityName, entityId, opts = {}) {
|
||||
opts.preview = !!opts.preview;
|
||||
|
||||
function getBlobPojo(entityName, entityId) {
|
||||
const entity = becca.getEntity(entityName, entityId);
|
||||
|
||||
if (!entity) {
|
||||
@ -19,10 +17,6 @@ function getBlobPojo(entityName, entityId, opts = {}) {
|
||||
pojo.content = null;
|
||||
} else {
|
||||
pojo.content = processContent(pojo.content, entity.isProtected, true);
|
||||
|
||||
if (opts.preview && pojo.content.length > 10000) {
|
||||
pojo.content = `${pojo.content.substr(0, 10000)}\r\n\r\n... and ${pojo.content.length - 10000} more characters.`;
|
||||
}
|
||||
}
|
||||
|
||||
return pojo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user