Auto-refresh images on edit
Only for Markdown images, not drawing blocks, since those will eventually be deprecated.
This commit is contained in:
		
							parent
							
								
									5e51589ffa
								
							
						
					
					
						commit
						e9a9961b61
					
				
					 4 changed files with 33 additions and 5 deletions
				
			
		|  | @ -6,3 +6,4 @@ export const STORAGE_PATH = DATA_PATH + "storage/petal/siyuan-jsdraw-plugin"; | ||||||
| export const TOOLBAR_PATH = STORAGE_PATH + "/toolbar.json"; | export const TOOLBAR_PATH = STORAGE_PATH + "/toolbar.json"; | ||||||
| export const CONFIG_PATH = STORAGE_PATH + "/conf.json"; | export const CONFIG_PATH = STORAGE_PATH + "/conf.json"; | ||||||
| export const EMBED_PATH = "/plugins/siyuan-jsdraw-plugin/webapp/?path="; | export const EMBED_PATH = "/plugins/siyuan-jsdraw-plugin/webapp/?path="; | ||||||
|  | export const DUMMY_HOST = "https://dummy.host/"; | ||||||
|  | @ -5,6 +5,7 @@ import 'js-draw/styles'; | ||||||
| import {getFile, saveFile} from "@/file"; | import {getFile, saveFile} from "@/file"; | ||||||
| import {DATA_PATH, JSON_MIME, SVG_MIME, TOOLBAR_PATH} from "@/const"; | import {DATA_PATH, JSON_MIME, SVG_MIME, TOOLBAR_PATH} from "@/const"; | ||||||
| import {idToPath} from "@/helper"; | import {idToPath} from "@/helper"; | ||||||
|  | import {replaceAntiCacheID} from "@/protyle"; | ||||||
| 
 | 
 | ||||||
| export function openEditorTab(p: Plugin, path: string) { | export function openEditorTab(p: Plugin, path: string) { | ||||||
|     openTab({ |     openTab({ | ||||||
|  | @ -22,6 +23,7 @@ async function saveCallback(editor: Editor, path: string, saveButton: BaseWidget | ||||||
|     const svgElem = editor.toSVG(); |     const svgElem = editor.toSVG(); | ||||||
|     try { |     try { | ||||||
|         saveFile(DATA_PATH + path, SVG_MIME, svgElem.outerHTML); |         saveFile(DATA_PATH + path, SVG_MIME, svgElem.outerHTML); | ||||||
|  |         await replaceAntiCacheID(path); | ||||||
|         saveButton.setDisabled(true); |         saveButton.setDisabled(true); | ||||||
|         setTimeout(() => { // @todo improve save button feedback
 |         setTimeout(() => { // @todo improve save button feedback
 | ||||||
|             saveButton.setDisabled(false); |             saveButton.setDisabled(false); | ||||||
|  |  | ||||||
|  | @ -1,12 +1,12 @@ | ||||||
| import {getBlockByID, sql, updateBlock} from "@/api"; | import {getBlockByID, sql, updateBlock} from "@/api"; | ||||||
| import {escapeRegExp} from "@/helper"; | import {DUMMY_HOST} from "@/const"; | ||||||
| 
 | 
 | ||||||
| export async function findImageBlocks(src: string) { | export async function findImageBlocks(src: string) { | ||||||
| 
 | 
 | ||||||
|     const sqlQuery = ` |     const sqlQuery = ` | ||||||
|         SELECT id, markdown  |         SELECT id, markdown  | ||||||
|         FROM blocks  |         FROM blocks  | ||||||
|         WHERE markdown like '%${src}%' |         WHERE markdown like '%](${src}%' // "](" is to check it's an image src
 | ||||||
|     `;
 |     `;
 | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
|  | @ -30,7 +30,7 @@ export async function replaceBlockContent( | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const originalContent = block.markdown; |         const originalContent = block.markdown; | ||||||
|         const newContent = originalContent.replace(escapeRegExp(searchStr), replaceStr); |         const newContent = originalContent.replaceAll(searchStr, replaceStr); | ||||||
| 
 | 
 | ||||||
|         if (newContent === originalContent) { |         if (newContent === originalContent) { | ||||||
|             return false; |             return false; | ||||||
|  | @ -44,3 +44,28 @@ export async function replaceBlockContent( | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export async function replaceAntiCacheID(src: string) { | ||||||
|  | 
 | ||||||
|  |     const search = encodeURI(src); // the API uses URI-encoded
 | ||||||
|  |     // find blocks containing that image
 | ||||||
|  |     const blocks = await findImageBlocks(search); | ||||||
|  | 
 | ||||||
|  |     for(const block of blocks) { | ||||||
|  | 
 | ||||||
|  |         // get all the image sources, with parameters
 | ||||||
|  |         const markdown = block.markdown; | ||||||
|  |         const imageRegex = /!\[.*?\]\((.*?)\)/g; // only get images
 | ||||||
|  |         const sources = Array.from(markdown.matchAll(imageRegex)) | ||||||
|  |             .map(match => match[1]) | ||||||
|  |             .filter(source => source.startsWith(search)) // discard other images
 | ||||||
|  | 
 | ||||||
|  |         for(const source of sources) { | ||||||
|  |             const url = new URL(source, DUMMY_HOST); | ||||||
|  |             url.searchParams.set('antiCache', Date.now().toString()); // set or replace antiCache
 | ||||||
|  |             const newSource =  url.href.replace(DUMMY_HOST, ''); | ||||||
|  |             await replaceBlockContent(block.id, source, newSource); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
|         "useDefineForClassFields": true, |         "useDefineForClassFields": true, | ||||||
|         "module": "ESNext", |         "module": "ESNext", | ||||||
|         "lib": [ |         "lib": [ | ||||||
|             "ES2020", |             "ES2021", | ||||||
|             "DOM", |             "DOM", | ||||||
|             "DOM.Iterable" |             "DOM.Iterable" | ||||||
|         ], |         ], | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue