@qnote/q-ai-note 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../../src/server/api/images.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA0FxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,89 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { Router } from 'express';
4
+ import { randomUUID } from 'crypto';
5
+ import { getResolvedDbPath } from '../db.js';
6
+ import { forbid, getAccessContextFromResponse } from './accessHelpers.js';
7
+ const router = Router();
8
+ const MAX_IMAGE_SIZE_BYTES = 20 * 1024 * 1024;
9
+ const IMAGE_EXT_BY_MIME = {
10
+ 'image/png': 'png',
11
+ 'image/jpeg': 'jpg',
12
+ 'image/jpg': 'jpg',
13
+ 'image/webp': 'webp',
14
+ 'image/gif': 'gif',
15
+ };
16
+ function ensureDir(dirPath) {
17
+ if (!fs.existsSync(dirPath)) {
18
+ fs.mkdirSync(dirPath, { recursive: true });
19
+ }
20
+ }
21
+ function normalizeBase64(input) {
22
+ const raw = String(input || '').trim();
23
+ if (!raw)
24
+ return '';
25
+ const marker = ';base64,';
26
+ const markerIdx = raw.indexOf(marker);
27
+ if (raw.startsWith('data:') && markerIdx >= 0) {
28
+ return raw.slice(markerIdx + marker.length).trim();
29
+ }
30
+ return raw;
31
+ }
32
+ function pickExtension(mimeType, filename = '') {
33
+ const mime = String(mimeType || '').trim().toLowerCase();
34
+ if (IMAGE_EXT_BY_MIME[mime])
35
+ return IMAGE_EXT_BY_MIME[mime];
36
+ const ext = path.extname(String(filename || '').trim()).replace('.', '').toLowerCase();
37
+ if (ext && ['png', 'jpg', 'jpeg', 'webp', 'gif'].includes(ext)) {
38
+ return ext === 'jpeg' ? 'jpg' : ext;
39
+ }
40
+ return '';
41
+ }
42
+ router.post('/', (req, res) => {
43
+ try {
44
+ const access = getAccessContextFromResponse(res);
45
+ const hasWritablePage = Boolean(access.full_access
46
+ || access.page_access?.sandboxes
47
+ || access.page_access?.diaries
48
+ || access.page_access?.ai_engineering);
49
+ if (!hasWritablePage) {
50
+ return forbid(res, 'No permission to upload images');
51
+ }
52
+ const mimeType = String(req.body?.mime_type || '').trim().toLowerCase();
53
+ const filename = String(req.body?.filename || '').trim();
54
+ const dataBase64 = normalizeBase64(String(req.body?.data_base64 || ''));
55
+ if (!dataBase64) {
56
+ return res.status(400).json({ success: false, error: 'data_base64 is required' });
57
+ }
58
+ const extension = pickExtension(mimeType, filename);
59
+ if (!extension) {
60
+ return res.status(400).json({ success: false, error: 'Unsupported image type' });
61
+ }
62
+ const buffer = Buffer.from(dataBase64, 'base64');
63
+ if (!buffer.length) {
64
+ return res.status(400).json({ success: false, error: 'Invalid image payload' });
65
+ }
66
+ if (buffer.length > MAX_IMAGE_SIZE_BYTES) {
67
+ return res.status(413).json({ success: false, error: 'Image too large (max 20MB)' });
68
+ }
69
+ const dataDir = getResolvedDbPath();
70
+ const imagesDir = path.join(dataDir, 'images');
71
+ ensureDir(imagesDir);
72
+ const savedFileName = `${Date.now()}-${randomUUID()}.${extension}`;
73
+ const outputPath = path.join(imagesDir, savedFileName);
74
+ fs.writeFileSync(outputPath, buffer);
75
+ return res.status(201).json({
76
+ success: true,
77
+ data: {
78
+ url: `/images/${savedFileName}`,
79
+ file_name: savedFileName,
80
+ size_bytes: buffer.length,
81
+ },
82
+ });
83
+ }
84
+ catch (error) {
85
+ return res.status(500).json({ success: false, error: String(error) });
86
+ }
87
+ });
88
+ export default router;
89
+ //# sourceMappingURL=images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.js","sourceRoot":"","sources":["../../../src/server/api/images.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA2BxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAkBD,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,OAAO,GAAG,YAAoB,EAC3C,UAAU,GAAE,GAAG,CAAC,MAAM,CAAqB,EAC3C,mBAAmB,GAAE,GAAG,CAAC,MAAM,CAAqB,GACnD,OAAO,CAOT;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,OAAO,GAAG,YAAoB,EAC3C,UAAU,GAAE,GAAG,CAAC,MAAM,CAAqB,GAC1C,OAAO,CAKT;AAYD,wBAAgB,SAAS,CAAC,WAAW,GAAE,OAAO,GAAG,YAAuB,+CAwEvE;AAED,wBAAgB,WAAW,CACzB,IAAI,SAAO,EACX,IAAI,SAAO,EACX,WAAW,GAAE,OAAO,GAAG,YAAuE,GAC7F,MAAM,CAmBR;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBhD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA6BxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAkBD,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,OAAO,GAAG,YAAoB,EAC3C,UAAU,GAAE,GAAG,CAAC,MAAM,CAAqB,EAC3C,mBAAmB,GAAE,GAAG,CAAC,MAAM,CAAqB,GACnD,OAAO,CAOT;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,OAAO,GAAG,YAAoB,EAC3C,UAAU,GAAE,GAAG,CAAC,MAAM,CAAqB,GAC1C,OAAO,CAKT;AAYD,wBAAgB,SAAS,CAAC,WAAW,GAAE,OAAO,GAAG,YAAuB,+CA0EvE;AAED,wBAAgB,WAAW,CACzB,IAAI,SAAO,EACX,IAAI,SAAO,EACX,WAAW,GAAE,OAAO,GAAG,YAAuE,GAC7F,MAAM,CAmBR;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBhD"}
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import os from 'os';
4
4
  import { fileURLToPath, pathToFileURL } from 'url';
5
5
  import { initDb, closeDb } from './db.js';
6
+ import { getResolvedDbPath } from './db.js';
6
7
  import sandboxRouter from './api/sandbox.js';
7
8
  import workItemRouter from './api/workItem.js';
8
9
  import diaryRouter from './api/diary.js';
@@ -11,6 +12,7 @@ import settingsRouter from './api/settings.js';
11
12
  import nodeEntitiesRouter from './api/nodeEntities.js';
12
13
  import projectSettingsRouter from './api/projectSettings.js';
13
14
  import aserRuntimeRouter from './api/aserRuntime.js';
15
+ import imagesRouter from './api/images.js';
14
16
  import { getAccessContext, normalizeIpAddress as normalizeIpAddressFromAccess, } from './accessControl.js';
15
17
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
18
  const PORT = Number(process.env.PORT || 3000);
@@ -72,9 +74,10 @@ export function createApp(inputPolicy = READONLY) {
72
74
  localIpSet,
73
75
  });
74
76
  const app = express();
75
- app.use(express.json());
77
+ app.use(express.json({ limit: '25mb' }));
76
78
  app.use('/node_modules', express.static(path.join(__dirname, '../../node_modules')));
77
79
  app.use(express.static(path.join(__dirname, '../web')));
80
+ app.use('/images', express.static(path.join(getResolvedDbPath(), 'images')));
78
81
  app.get('/api/runtime', (req, res) => {
79
82
  const access = getRequestAccessContext(req);
80
83
  res.json({
@@ -119,6 +122,7 @@ export function createApp(inputPolicy = READONLY) {
119
122
  app.use('/api/items', workItemRouter);
120
123
  app.use('/api/diaries', diaryRouter);
121
124
  app.use('/api/chats', chatRouter);
125
+ app.use('/api/images', imagesRouter);
122
126
  app.use('/api/settings', settingsRouter);
123
127
  app.use('/api/project-settings', projectSettingsRouter);
124
128
  app.use('/api/sandboxes/:sandboxId/entities', nodeEntitiesRouter);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
package/dist/web/app.js CHANGED
@@ -1209,20 +1209,27 @@ function renderWorkTree() {
1209
1209
  if (fromIdx < 0) return;
1210
1210
  const toIdx = fromIdx + delta;
1211
1211
  if (toIdx < 0 || toIdx >= siblings.length) return;
1212
- const peers = siblings.filter((item) => item.id !== nodeId);
1213
- const left = peers[toIdx - 1] || null;
1214
- const right = peers[toIdx] || null;
1212
+ const reordered = [...siblings];
1213
+ const [movedNode] = reordered.splice(fromIdx, 1);
1214
+ reordered.splice(toIdx, 0, movedNode);
1215
+ const left = reordered[toIdx - 1] || null;
1216
+ const right = reordered[toIdx + 1] || null;
1215
1217
  const nextOrderKey = rankBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'));
1216
- if (nextOrderKey === getNodeOrderKey(node, 'order_key')) return;
1217
- await apiRequest(`${API_BASE}/items/${nodeId}`, {
1218
- method: 'PUT',
1219
- body: JSON.stringify({
1220
- extra_data: {
1221
- ...(node.extra_data || {}),
1222
- order_key: nextOrderKey,
1223
- },
1224
- }),
1225
- });
1218
+ const canDirectUpdate = nextOrderKey !== getNodeOrderKey(node, 'order_key')
1219
+ && isOrderKeyBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'), nextOrderKey);
1220
+ if (canDirectUpdate) {
1221
+ await apiRequest(`${API_BASE}/items/${nodeId}`, {
1222
+ method: 'PUT',
1223
+ body: JSON.stringify({
1224
+ extra_data: {
1225
+ ...(node.extra_data || {}),
1226
+ order_key: nextOrderKey,
1227
+ },
1228
+ }),
1229
+ });
1230
+ } else {
1231
+ await persistSiblingOrderByList(reordered, parentId);
1232
+ }
1226
1233
  await loadSandbox(state.currentSandbox.id);
1227
1234
  },
1228
1235
  onReorderSiblings: treeReadonly ? undefined : async (dragNodeId, targetNodeId, position) => {
@@ -1243,19 +1250,30 @@ function renderWorkTree() {
1243
1250
  const targetIndex = siblings.findIndex((item) => item.id === targetNodeId);
1244
1251
  if (targetIndex < 0) return;
1245
1252
  const insertIndex = position === 'after' ? targetIndex + 1 : targetIndex;
1246
- const left = siblings[insertIndex - 1] || null;
1247
- const right = siblings[insertIndex] || null;
1253
+ const reordered = [...siblings];
1254
+ reordered.splice(insertIndex, 0, dragNode);
1255
+ const left = reordered[insertIndex - 1] || null;
1256
+ const right = reordered[insertIndex + 1] || null;
1248
1257
  const nextOrderKey = rankBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'));
1249
- await apiRequest(`${API_BASE}/items/${dragNodeId}`, {
1250
- method: 'PUT',
1251
- body: JSON.stringify({
1252
- parent_id: nextParentId,
1253
- extra_data: {
1254
- ...(dragNode.extra_data || {}),
1255
- order_key: nextOrderKey,
1256
- },
1257
- }),
1258
- });
1258
+ const canDirectUpdate = isOrderKeyBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'), nextOrderKey)
1259
+ && (
1260
+ nextOrderKey !== getNodeOrderKey(dragNode, 'order_key')
1261
+ || (dragNode.parent_id || null) !== nextParentId
1262
+ );
1263
+ if (canDirectUpdate) {
1264
+ await apiRequest(`${API_BASE}/items/${dragNodeId}`, {
1265
+ method: 'PUT',
1266
+ body: JSON.stringify({
1267
+ parent_id: nextParentId,
1268
+ extra_data: {
1269
+ ...(dragNode.extra_data || {}),
1270
+ order_key: nextOrderKey,
1271
+ },
1272
+ }),
1273
+ });
1274
+ } else {
1275
+ await persistSiblingOrderByList(reordered, nextParentId, dragNodeId);
1276
+ }
1259
1277
  await loadSandbox(state.currentSandbox.id);
1260
1278
  },
1261
1279
  onReorderLanes: treeReadonly ? undefined : async (dragRootId, targetRootId, position = 'before') => {
@@ -1409,6 +1427,55 @@ function rankBetween(left, right) {
1409
1427
  return `${prefix}${ORDER_ALPHABET[Math.floor(ORDER_BASE / 2)]}`;
1410
1428
  }
1411
1429
 
1430
+ function encodeOrderIndex(index, width = 6) {
1431
+ let value = Number.isFinite(index) ? Math.max(0, Math.floor(index)) : 0;
1432
+ let encoded = '';
1433
+ do {
1434
+ const digit = value % ORDER_BASE;
1435
+ encoded = `${ORDER_ALPHABET[digit]}${encoded}`;
1436
+ value = Math.floor(value / ORDER_BASE);
1437
+ } while (value > 0);
1438
+ return encoded.padStart(width, ORDER_ALPHABET[0]);
1439
+ }
1440
+
1441
+ function isOrderKeyBetween(leftKey, rightKey, candidateKey) {
1442
+ const left = String(leftKey || '');
1443
+ const right = String(rightKey || '');
1444
+ const candidate = String(candidateKey || '');
1445
+ if (!candidate) return false;
1446
+ if (left && candidate <= left) return false;
1447
+ if (right && candidate >= right) return false;
1448
+ return true;
1449
+ }
1450
+
1451
+ async function persistSiblingOrderByList(orderedItems, nextParentId = null, movedNodeId = '') {
1452
+ const items = Array.isArray(orderedItems) ? orderedItems : [];
1453
+ for (let index = 0; index < items.length; index += 1) {
1454
+ const item = items[index];
1455
+ if (!item?.id) continue;
1456
+ const targetKey = encodeOrderIndex((index + 1) * 1024);
1457
+ const currentKey = getNodeOrderKey(item, 'order_key');
1458
+ const isMovedNode = Boolean(movedNodeId) && String(item.id) === String(movedNodeId);
1459
+ const currentParentId = item.parent_id || null;
1460
+ const needsParentUpdate = isMovedNode && currentParentId !== nextParentId;
1461
+ const needsOrderUpdate = currentKey !== targetKey;
1462
+ if (!needsParentUpdate && !needsOrderUpdate) continue;
1463
+ const body = {
1464
+ extra_data: {
1465
+ ...(item.extra_data || {}),
1466
+ order_key: targetKey,
1467
+ },
1468
+ };
1469
+ if (needsParentUpdate) {
1470
+ body.parent_id = nextParentId;
1471
+ }
1472
+ await apiRequest(`${API_BASE}/items/${item.id}`, {
1473
+ method: 'PUT',
1474
+ body: JSON.stringify(body),
1475
+ });
1476
+ }
1477
+ }
1478
+
1412
1479
  function getNodeOrderKey(item, keyName = 'order_key') {
1413
1480
  return String(item?.extra_data?.[keyName] || '').trim();
1414
1481
  }
@@ -1525,10 +1592,15 @@ function renderMarkdownSnippet(text, options = {}) {
1525
1592
 
1526
1593
  const renderInline = (raw) => {
1527
1594
  let html = safeText(String(raw || ''));
1595
+ html = html.replace(/!\[([^\]]*)\]\(((?:https?:\/\/|\/)[^\s)]+)\)/g, (_m, alt, url) => {
1596
+ const safeUrl = safeText(url);
1597
+ const safeAlt = safeText(alt || 'image');
1598
+ return `<img src="${safeUrl}" alt="${safeAlt}" loading="lazy">`;
1599
+ });
1528
1600
  html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
1529
1601
  html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
1530
1602
  html = html.replace(/\*([^*]+)\*/g, '<em>$1</em>');
1531
- html = html.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g, (_m, label, url) => {
1603
+ html = html.replace(/\[([^\]]+)\]\(((?:https?:\/\/|\/)[^\s)]+)\)/g, (_m, label, url) => {
1532
1604
  const safeUrl = safeText(url);
1533
1605
  const safeLabel = safeText(label);
1534
1606
  return `<a href="${safeUrl}" target="_blank" rel="noopener noreferrer">${safeLabel}</a>`;
@@ -3667,8 +3739,204 @@ function editWorkItem(id) {
3667
3739
  document.getElementById('item-dialog').showModal();
3668
3740
  }
3669
3741
 
3742
+ const MARKDOWN_PASTE_TEXTAREA_IDS = [
3743
+ 'diary-content',
3744
+ 'diary-edit-content',
3745
+ 'entity-content-input',
3746
+ 'drawer-diary-content',
3747
+ 'drawer-work-item-description',
3748
+ 'new-item-desc',
3749
+ ];
3750
+
3751
+ function readFileAsDataUrl(file) {
3752
+ return new Promise((resolve, reject) => {
3753
+ const reader = new FileReader();
3754
+ reader.onload = () => resolve(String(reader.result || ''));
3755
+ reader.onerror = () => reject(new Error('读取图片失败'));
3756
+ reader.readAsDataURL(file);
3757
+ });
3758
+ }
3759
+
3760
+ function isStandaloneHttpUrl(text) {
3761
+ const value = String(text || '').trim();
3762
+ if (!value || /\s/.test(value)) return false;
3763
+ return /^https?:\/\/[^\s]+$/i.test(value);
3764
+ }
3765
+
3766
+ function deriveMarkdownLinkName(urlText) {
3767
+ try {
3768
+ const parsed = new URL(String(urlText || '').trim());
3769
+ const segments = String(parsed.pathname || '')
3770
+ .split('/')
3771
+ .map((segment) => segment.trim())
3772
+ .filter((segment) => Boolean(segment));
3773
+ if (!segments.length) return '链接';
3774
+ const lastSegment = decodeURIComponent(segments[segments.length - 1] || '').trim();
3775
+ if (!lastSegment) return '链接';
3776
+ const withoutExt = lastSegment
3777
+ .replace(/\.(?:html?|xhtml|shtml|php|asp|aspx|jsp)$/i, '')
3778
+ .trim();
3779
+ const normalized = withoutExt
3780
+ .replace(/[-_]+/g, ' ')
3781
+ .replace(/\s+/g, ' ')
3782
+ .trim();
3783
+ return normalized || '链接';
3784
+ } catch {
3785
+ return '链接';
3786
+ }
3787
+ }
3788
+
3789
+ function insertTextAtCursor(textarea, text) {
3790
+ const start = Number(textarea.selectionStart || 0);
3791
+ const end = Number(textarea.selectionEnd || 0);
3792
+ const value = String(textarea.value || '');
3793
+ const prefix = value.slice(0, start);
3794
+ const suffix = value.slice(end);
3795
+ const prefixBreak = prefix.length > 0 && !prefix.endsWith('\n') ? '\n' : '';
3796
+ const suffixBreak = suffix.length > 0 && !suffix.startsWith('\n') ? '\n' : '';
3797
+ const inserted = `${prefixBreak}${text}${suffixBreak}`;
3798
+ textarea.value = `${prefix}${inserted}${suffix}`;
3799
+ const nextCaret = prefix.length + inserted.length;
3800
+ textarea.selectionStart = nextCaret;
3801
+ textarea.selectionEnd = nextCaret;
3802
+ textarea.dispatchEvent(new Event('input', { bubbles: true }));
3803
+ }
3804
+
3805
+ async function uploadPastedImage(file) {
3806
+ const dataUrl = await readFileAsDataUrl(file);
3807
+ const marker = ';base64,';
3808
+ const markerIdx = dataUrl.indexOf(marker);
3809
+ if (markerIdx < 0) {
3810
+ throw new Error('无法解析图片数据');
3811
+ }
3812
+ const dataBase64 = dataUrl.slice(markerIdx + marker.length).trim();
3813
+ const response = await fetch(`${API_BASE}/images`, {
3814
+ method: 'POST',
3815
+ headers: { 'Content-Type': 'application/json' },
3816
+ body: JSON.stringify({
3817
+ filename: file.name || '',
3818
+ mime_type: file.type || '',
3819
+ data_base64: dataBase64,
3820
+ }),
3821
+ });
3822
+ const result = await response.json();
3823
+ if (!response.ok || !result?.success || !result?.data?.url) {
3824
+ throw new Error(result?.error || '图片上传失败');
3825
+ }
3826
+ return String(result.data.url);
3827
+ }
3828
+
3829
+ function bindMarkdownPasteForTextarea(textarea) {
3830
+ if (!(textarea instanceof HTMLTextAreaElement)) return;
3831
+ if (textarea.dataset.mdPasteImageBound === '1') return;
3832
+ textarea.dataset.mdPasteImageBound = '1';
3833
+ textarea.addEventListener('paste', async (event) => {
3834
+ const items = Array.from(event.clipboardData?.items || []);
3835
+ const imageFiles = items
3836
+ .filter((item) => item.kind === 'file' && String(item.type || '').startsWith('image/'))
3837
+ .map((item) => item.getAsFile())
3838
+ .filter((file) => Boolean(file));
3839
+ if (imageFiles.length) {
3840
+ event.preventDefault();
3841
+ const errors = [];
3842
+ for (const file of imageFiles) {
3843
+ try {
3844
+ const imageUrl = await uploadPastedImage(file);
3845
+ insertTextAtCursor(textarea, `![image](${imageUrl})`);
3846
+ } catch (error) {
3847
+ errors.push(error);
3848
+ }
3849
+ }
3850
+ if (errors.length) {
3851
+ alert(`粘贴图片失败:${String(errors[0]?.message || errors[0])}`);
3852
+ }
3853
+ return;
3854
+ }
3855
+ const plainText = String(event.clipboardData?.getData('text/plain') || '').trim();
3856
+ if (!isStandaloneHttpUrl(plainText)) return;
3857
+ const linkName = deriveMarkdownLinkName(plainText);
3858
+ event.preventDefault();
3859
+ insertTextAtCursor(textarea, `[${linkName}](${plainText})`);
3860
+ if (typeof textarea.focus === 'function') {
3861
+ textarea.focus();
3862
+ }
3863
+ });
3864
+ }
3865
+
3866
+ function initMarkdownImagePasteSupport() {
3867
+ MARKDOWN_PASTE_TEXTAREA_IDS.forEach((id) => {
3868
+ const el = document.getElementById(id);
3869
+ if (el instanceof HTMLTextAreaElement) {
3870
+ bindMarkdownPasteForTextarea(el);
3871
+ }
3872
+ });
3873
+ }
3874
+
3875
+ let markdownImageLightboxEl = null;
3876
+
3877
+ function ensureMarkdownImageLightbox() {
3878
+ if (markdownImageLightboxEl instanceof HTMLElement) {
3879
+ return markdownImageLightboxEl;
3880
+ }
3881
+ const overlay = document.createElement('div');
3882
+ overlay.className = 'image-lightbox hidden';
3883
+ overlay.id = 'image-lightbox';
3884
+ overlay.innerHTML = `
3885
+ <div class="image-lightbox-backdrop" data-action="close"></div>
3886
+ <div class="image-lightbox-content">
3887
+ <img id="image-lightbox-img" alt="preview image">
3888
+ </div>
3889
+ `;
3890
+ document.body.appendChild(overlay);
3891
+ overlay.addEventListener('click', (event) => {
3892
+ const target = event.target;
3893
+ if (target instanceof HTMLElement && target.dataset.action === 'close') {
3894
+ event.preventDefault();
3895
+ event.stopPropagation();
3896
+ overlay.classList.add('hidden');
3897
+ overlay.setAttribute('aria-hidden', 'true');
3898
+ }
3899
+ });
3900
+ markdownImageLightboxEl = overlay;
3901
+ return overlay;
3902
+ }
3903
+
3904
+ function openMarkdownImageLightbox(src, alt = '') {
3905
+ const overlay = ensureMarkdownImageLightbox();
3906
+ const img = overlay.querySelector('#image-lightbox-img');
3907
+ if (!(img instanceof HTMLImageElement)) return;
3908
+ img.src = String(src || '');
3909
+ img.alt = String(alt || 'preview image');
3910
+ overlay.classList.remove('hidden');
3911
+ overlay.setAttribute('aria-hidden', 'false');
3912
+ }
3913
+
3914
+ function initMarkdownImageLightboxSupport() {
3915
+ document.addEventListener('click', (event) => {
3916
+ const target = event.target;
3917
+ if (!(target instanceof HTMLImageElement)) return;
3918
+ if (!target.closest('.diary-content, .entity-content, .chat-message.assistant')) return;
3919
+ const src = String(target.getAttribute('src') || '').trim();
3920
+ if (!src) return;
3921
+ event.preventDefault();
3922
+ openMarkdownImageLightbox(src, String(target.getAttribute('alt') || ''));
3923
+ });
3924
+ document.addEventListener('keydown', (event) => {
3925
+ if (event.key !== 'Escape') return;
3926
+ const overlay = markdownImageLightboxEl;
3927
+ if (!(overlay instanceof HTMLElement)) return;
3928
+ if (overlay.classList.contains('hidden')) return;
3929
+ event.preventDefault();
3930
+ event.stopPropagation();
3931
+ overlay.classList.add('hidden');
3932
+ overlay.setAttribute('aria-hidden', 'true');
3933
+ });
3934
+ }
3935
+
3670
3936
  async function initApp() {
3671
3937
  await loadRuntimeMode();
3938
+ initMarkdownImagePasteSupport();
3939
+ initMarkdownImageLightboxSupport();
3672
3940
  loadWorkItemAssigneePreference();
3673
3941
  loadWorkTreeViewModePreference();
3674
3942
  loadSandboxSortModePreference();
@@ -4198,6 +4466,7 @@ async function initApp() {
4198
4466
  if (!drawer || drawer.classList.contains('hidden')) return;
4199
4467
  const target = event.target;
4200
4468
  if (!(target instanceof Node)) return;
4469
+ if (target instanceof HTMLElement && target.closest('#image-lightbox')) return;
4201
4470
  if (drawer.contains(target)) return;
4202
4471
  if (workTree?.contains(target)) return;
4203
4472
  closeNodeEntityDrawer();
@@ -2900,6 +2900,68 @@ h2 {
2900
2900
  font-size: 12px;
2901
2901
  }
2902
2902
 
2903
+ .diary-content img,
2904
+ .entity-content img,
2905
+ .chat-message.assistant img {
2906
+ max-width: min(100%, 820px);
2907
+ max-height: min(56vh, 520px);
2908
+ height: auto;
2909
+ width: auto;
2910
+ object-fit: contain;
2911
+ border-radius: 6px;
2912
+ display: block;
2913
+ margin: 10px 0;
2914
+ cursor: zoom-in;
2915
+ border: 1px solid #d8e0ec;
2916
+ background: #f8fafd;
2917
+ box-shadow: 0 6px 16px rgba(18, 42, 76, 0.12);
2918
+ padding: 4px;
2919
+ }
2920
+
2921
+ .image-lightbox {
2922
+ position: fixed;
2923
+ inset: 0;
2924
+ z-index: 2000;
2925
+ display: flex;
2926
+ align-items: center;
2927
+ justify-content: center;
2928
+ }
2929
+
2930
+ .image-lightbox.hidden {
2931
+ display: none;
2932
+ }
2933
+
2934
+ .image-lightbox-backdrop {
2935
+ position: absolute;
2936
+ inset: 0;
2937
+ background: rgba(0, 0, 0, 0.68);
2938
+ }
2939
+
2940
+ .image-lightbox-content {
2941
+ position: relative;
2942
+ width: auto;
2943
+ max-width: 92vw;
2944
+ max-height: 92vh;
2945
+ padding: 0;
2946
+ border-radius: 0;
2947
+ background: transparent;
2948
+ box-shadow: none;
2949
+ display: flex;
2950
+ align-items: center;
2951
+ justify-content: center;
2952
+ }
2953
+
2954
+ .image-lightbox-content img {
2955
+ display: block;
2956
+ max-width: 92vw;
2957
+ max-height: 92vh;
2958
+ width: auto;
2959
+ height: auto;
2960
+ border-radius: 6px;
2961
+ margin: 0;
2962
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
2963
+ }
2964
+
2903
2965
  .diary-actions {
2904
2966
  display: flex;
2905
2967
  flex-wrap: wrap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qnote/q-ai-note",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "type": "module",
5
5
  "description": "AI-assisted personal work sandbox and diary system",
6
6
  "main": "dist/server/index.js",