mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	share functionality WIP
This commit is contained in:
		
							parent
							
								
									67da877135
								
							
						
					
					
						commit
						08e8047d8a
					
				| @ -1,8 +1,3 @@ | |||||||
| #title { |  | ||||||
|     margin: 0; |  | ||||||
|     padding-bottom: 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #layout { | #layout { | ||||||
|     max-width: 1200px; |     max-width: 1200px; | ||||||
|     margin: 0 auto; |     margin: 0 auto; | ||||||
| @ -32,10 +27,24 @@ | |||||||
|     background-color:#eee; |     background-color:#eee; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #title, #content { | #title { | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 20px 20px 0 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #content { | ||||||
|     padding: 20px; |     padding: 20px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .type-image img { | ||||||
|  |     max-width: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pre { | ||||||
|  |     white-space: pre-wrap; | ||||||
|  |     word-wrap: anywhere; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #menuLink { | #menuLink { | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     display: block; |     display: block; | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| const shaca = require("./shaca/shaca"); | const shaca = require("./shaca/shaca"); | ||||||
| const shacaLoader = require("./shaca/shaca_loader"); | const shacaLoader = require("./shaca/shaca_loader"); | ||||||
| const shareRoot = require("./share_root"); | const shareRoot = require("./share_root"); | ||||||
| const utils = require("../services/utils"); |  | ||||||
| const {JSDOM} = require("jsdom"); | const {JSDOM} = require("jsdom"); | ||||||
| 
 | 
 | ||||||
| function getSubRoot(note) { | function getSubRoot(note) { | ||||||
| @ -47,16 +46,27 @@ function getContent(note) { | |||||||
|     let content = note.getContent(); |     let content = note.getContent(); | ||||||
| 
 | 
 | ||||||
|     if (note.type === 'text') { |     if (note.type === 'text') { | ||||||
|         const isEmpty = !content?.trim() || (function() { |         const document = new JSDOM(content || "").window.document; | ||||||
|             const document = new JSDOM(content).window.document; |  | ||||||
| 
 | 
 | ||||||
|             return document.body.textContent.trim().length === 0 |         const isEmpty = document.body.textContent.trim().length === 0 | ||||||
|                 && document.querySelectorAll("img").length === 0; |                 && document.querySelectorAll("img").length === 0; | ||||||
|         })(); |  | ||||||
| 
 | 
 | ||||||
|         if (isEmpty) { |         if (isEmpty) { | ||||||
|             content = NO_CONTENT + getChildrenList(note); |             content = NO_CONTENT + getChildrenList(note); | ||||||
|         } |         } | ||||||
|  |         else { | ||||||
|  |             for (const linkEl of document.querySelectorAll("a")) { | ||||||
|  |                 const href = linkEl.getAttribute("href"); | ||||||
|  | 
 | ||||||
|  |                 if (href?.startsWith("#")) { | ||||||
|  |                     const notePathSegments = href.split("/"); | ||||||
|  | 
 | ||||||
|  |                     linkEl.setAttribute("href", notePathSegments[notePathSegments.length - 1]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             content = document.body.innerHTML; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else if (note.type === 'code') { |     else if (note.type === 'code') { | ||||||
|         if (!content?.trim()) { |         if (!content?.trim()) { | ||||||
| @ -66,11 +76,17 @@ function getContent(note) { | |||||||
|             const document = new JSDOM().window.document; |             const document = new JSDOM().window.document; | ||||||
| 
 | 
 | ||||||
|             const preEl = document.createElement('pre'); |             const preEl = document.createElement('pre'); | ||||||
|             preEl.innerText = content; |             preEl.appendChild(document.createTextNode(content)); | ||||||
| 
 | 
 | ||||||
|             content = preEl.outerHTML; |             content = preEl.outerHTML; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     else if (note.type === 'image') { | ||||||
|  |         content = `<img src="api/images/${note.noteId}/${note.title}?${note.utcDateModified}">`; | ||||||
|  |     } | ||||||
|  |     else if (note.type === 'file') { | ||||||
|  |         content = `<button type="button" onclick="location.href='api/notes/${note.noteId}/download'">Download file</button>`; | ||||||
|  |     } | ||||||
|     else if (note.type === 'book') { |     else if (note.type === 'book') { | ||||||
|         content = getChildrenList(note); |         content = getChildrenList(note); | ||||||
|     } |     } | ||||||
| @ -78,7 +94,7 @@ function getContent(note) { | |||||||
|         content = '<p>This note type cannot be displayed.</p>' + getChildrenList(note); |         content = '<p>This note type cannot be displayed.</p>' + getChildrenList(note); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return content; |     return `<div class="type-${note.type}">${content}</content>`; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function register(router) { | function register(router) { | ||||||
| @ -119,6 +135,26 @@ function register(router) { | |||||||
| 
 | 
 | ||||||
|         res.send(image.getContent()); |         res.send(image.getContent()); | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |     router.get('/share/api/notes/:noteId/:download', (req, res, next) => { | ||||||
|  |         const {noteId} = req.params; | ||||||
|  |         const note = shaca.getNote(noteId); | ||||||
|  | 
 | ||||||
|  |         if (!note) { | ||||||
|  |             return res.status(404).send(`Note ${noteId} doesn't exist.`); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const utils = require("../services/utils"); | ||||||
|  | 
 | ||||||
|  |         const filename = utils.formatDownloadTitle(note.title, note.type, note.mime); | ||||||
|  | 
 | ||||||
|  |         res.setHeader('Content-Disposition', utils.getContentDisposition(filename)); | ||||||
|  | 
 | ||||||
|  |         res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); | ||||||
|  |         res.setHeader('Content-Type', note.mime); | ||||||
|  | 
 | ||||||
|  |         res.send(note.getContent()); | ||||||
|  |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ const AbstractEntity = require('./abstract_entity'); | |||||||
| const shareRoot = require("../../share_root"); | const shareRoot = require("../../share_root"); | ||||||
| 
 | 
 | ||||||
| class Branch extends AbstractEntity { | class Branch extends AbstractEntity { | ||||||
|     constructor([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded]) { |     constructor([branchId, noteId, parentNoteId, prefix, isExpanded]) { | ||||||
|         super(); |         super(); | ||||||
| 
 | 
 | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
| @ -15,8 +15,6 @@ class Branch extends AbstractEntity { | |||||||
|         this.parentNoteId = parentNoteId; |         this.parentNoteId = parentNoteId; | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
|         this.prefix = prefix; |         this.prefix = prefix; | ||||||
|         /** @param {int} */ |  | ||||||
|         this.notePosition = notePosition; |  | ||||||
|         /** @param {boolean} */ |         /** @param {boolean} */ | ||||||
|         this.isExpanded = !!isExpanded; |         this.isExpanded = !!isExpanded; | ||||||
| 
 | 
 | ||||||
| @ -35,10 +33,6 @@ class Branch extends AbstractEntity { | |||||||
|             childNote.parentBranches.push(this); |             childNote.parentBranches.push(this); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!parentNote) { |  | ||||||
|             console.log(this); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!parentNote.children.includes(childNote)) { |         if (!parentNote.children.includes(childNote)) { | ||||||
|             parentNote.children.push(childNote); |             parentNote.children.push(childNote); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ const LABEL = 'label'; | |||||||
| const RELATION = 'relation'; | const RELATION = 'relation'; | ||||||
| 
 | 
 | ||||||
| class Note extends AbstractEntity { | class Note extends AbstractEntity { | ||||||
|     constructor([noteId, title, type, mime]) { |     constructor([noteId, title, type, mime, utcDateModified]) { | ||||||
|         super(); |         super(); | ||||||
| 
 | 
 | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
| @ -19,6 +19,8 @@ class Note extends AbstractEntity { | |||||||
|         this.type = type; |         this.type = type; | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
|         this.mime = mime; |         this.mime = mime; | ||||||
|  |         /** @param {string} */ | ||||||
|  |         this.utcDateModified = utcDateModified; // used for caching of images
 | ||||||
| 
 | 
 | ||||||
|         /** @param {Branch[]} */ |         /** @param {Branch[]} */ | ||||||
|         this.parentBranches = []; |         this.parentBranches = []; | ||||||
| @ -438,16 +440,6 @@ class Note extends AbstractEntity { | |||||||
|         return !!this.ownedAttributes.find(attr => attr.type === 'label' && attr.name === 'archived' && attr.isInheritable); |         return !!this.ownedAttributes.find(attr => attr.type === 'label' && attr.name === 'archived' && attr.isInheritable); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // will sort the parents so that non-search & non-archived are first and archived at the end
 |  | ||||||
|     // this is done so that non-search & non-archived paths are always explored as first when looking for note path
 |  | ||||||
|     resortParents() { |  | ||||||
|         this.parentBranches.sort((a, b) => |  | ||||||
|             a.branchId.startsWith('virt-') |  | ||||||
|             || a.parentNote.hasInheritableOwnedArchivedLabel() ? 1 : -1); |  | ||||||
| 
 |  | ||||||
|         this.parents = this.parentBranches.map(branch => branch.parentNote); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     isTemplate() { |     isTemplate() { | ||||||
|         return !!this.targetRelations.find(rel => rel.name === 'template'); |         return !!this.targetRelations.find(rel => rel.name === 'template'); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -33,11 +33,11 @@ function load() { | |||||||
| 
 | 
 | ||||||
|     const noteIdStr = noteIds.map(noteId => `'${noteId}'`).join(","); |     const noteIdStr = noteIds.map(noteId => `'${noteId}'`).join(","); | ||||||
| 
 | 
 | ||||||
|     for (const row of sql.getRawRows(`SELECT noteId, title, type, mime FROM notes WHERE isDeleted = 0 AND noteId IN (${noteIdStr})`)) { |     for (const row of sql.getRawRows(`SELECT noteId, title, type, mime, utcDateModified FROM notes WHERE isDeleted = 0 AND noteId IN (${noteIdStr})`)) { | ||||||
|         new Note(row); |         new Note(row); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (const row of sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0 AND noteId IN (${noteIdStr})`)) { |     for (const row of sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0 AND noteId IN (${noteIdStr}) ORDER BY notePosition`)) { | ||||||
|         new Branch(row); |         new Branch(row); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam