dsh-long-plugins 1.3.1 → 1.3.4
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.
- package/README.md +3 -1
- package/dsh.plugin.json +2 -2
- package/lib/index.js +70 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,12 +24,14 @@ Also ships an auto-repair install that relinks DSH core patches (reverse-proxy W
|
|
|
24
24
|
|
|
25
25
|
## 更新记录 / Releases
|
|
26
26
|
|
|
27
|
-
### v1.3.
|
|
27
|
+
### v1.3.2
|
|
28
28
|
|
|
29
29
|
**新增 · 顶栏「📂 文件」工作区浏览器 + Word 真实预览**:顶栏「📂文件」打开工作区/全部文件浏览,按文件夹分组;点文件名或「预览」在面板内预览。Word(`.docx`)走 `docx-preview` 浏览器端真实渲染(所见即所得,无需服务端转换),并随包打包前端库 `client/vendor`(docx-preview / jszip)。
|
|
30
30
|
|
|
31
31
|
**优化 · 两层关闭**:预览某文件时「✕关闭」/ Esc / 预览页自带「关闭」都回到文件列表,仅列表根部才整体退出面板;头部新增「←返回」按钮。Word 预览页也补上自带「✕关闭」,与 md 预览一致的两层关闭。
|
|
32
32
|
|
|
33
|
+
**新增 · PPT 真实预览(PptxViewJS)**:`.pptx` 也走浏览器端真实渲染(Canvas 逐页渲染、可翻页),与 docx 一致;随包打包 `client/vendor`(pptxviewjs / chart.js)。**优化 · 预览页固定顶栏**:Word / PPT / md 预览页顶部「下载 / ✕关闭」工具栏改为 sticky,滚动文档/幻灯片时不再被滚走。
|
|
34
|
+
|
|
33
35
|
### v1.3.0
|
|
34
36
|
|
|
35
37
|
**新增 · 拖放上传**:拖文件到网页任意位置松手即附加为「待发送」卡片;支持 `md / docx / xlsx / pptx / pdf / txt / csv` 及 `png / jpg / webp / gif`;与回形针同一条上传管线;拖放时全屏虚线投掷遮罩。
|
package/dsh.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-long-plugins",
|
|
3
|
-
"description": "Merged DSH web plugins: upload manager (drag-and-drop attach any file to the message), workspace output files, skill docs, account balance, Markdown-to-Word (md2docx), polished file preview,
|
|
4
|
-
"version": "1.3.
|
|
3
|
+
"description": "Merged DSH web plugins: upload manager (drag-and-drop attach any file to the message), workspace output files, skill docs, account balance, Markdown-to-Word (md2docx), and polished file preview (Word & PowerPoint real preview with zoom/pan, rendered Markdown), plus an auto-repair install for DSH core patches (reverse-proxy WebSocket heartbeat, upgrade relink). | 一个插件整合 DSH Web 的常用增强:上传管理(拖放上传:拖任意文件到会话框直接附加)、工作区「输出文件」面板、技能文档浏览、账户余额显示、Markdown 转 Word(md2docx)、Word/PowerPoint 真实预览(可缩放、翻页);并自带修复安装,自动重连 DSH 核心补丁(反代 WebSocket 心跳、升级重连)。",
|
|
4
|
+
"version": "1.3.4",
|
|
5
5
|
"entry": {
|
|
6
6
|
"name": "dsh-long-plugins",
|
|
7
7
|
"inject": [
|
package/lib/index.js
CHANGED
|
@@ -971,20 +971,29 @@ export function createHandlers(options = {}) {
|
|
|
971
971
|
<title>预览 - ${escapeHtml(name)}</title>
|
|
972
972
|
<style>
|
|
973
973
|
body{margin:0;background:#313b48;color:#1f2937}
|
|
974
|
-
#container{padding:16px 0}
|
|
974
|
+
#container{padding:16px 0;overflow:auto}
|
|
975
975
|
/* docx-preview 分页:每页一张"纸",页间留间隙(breakPages 模式下 .docx-wrapper 内每个 .docx 是一页) */
|
|
976
976
|
#container .docx-wrapper{background:transparent;padding:0;margin:0}
|
|
977
977
|
#container .docx-wrapper > .docx,
|
|
978
978
|
#container .docx-wrapper > section.docx,
|
|
979
|
-
#container .docx-wrapper section.docx{background:#fff;box-shadow:0 2px 12px rgba(0,0,0,.28);max-width:900px;margin:0
|
|
979
|
+
#container .docx-wrapper section.docx{background:#fff;box-shadow:0 2px 12px rgba(0,0,0,.28);max-width:900px;margin:0 0 24px;padding:56px 64px;box-sizing:border-box}
|
|
980
980
|
#container .docx-wrapper > .docx{min-height:1100px}
|
|
981
981
|
#container img{max-width:100%}
|
|
982
|
+
#container ._dsh-docx-stage{width:max-content !important;display:block !important}
|
|
983
|
+
#container ._dsh-docx-stage section.docx,
|
|
984
|
+
#container ._dsh-docx-stage .docx,
|
|
985
|
+
#container > .docx{margin:0 0 24px !important}
|
|
982
986
|
</style>
|
|
983
987
|
</head><body>
|
|
984
|
-
<div style="position:sticky;top:0;z-index:20;display:flex;gap:
|
|
985
|
-
<strong style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#e5e7eb">${escapeHtml(name)}</strong>
|
|
986
|
-
<
|
|
987
|
-
|
|
988
|
+
<div style="position:sticky;top:0;z-index:20;display:flex;gap:6px;padding:8px 12px;align-items:center;flex-wrap:wrap;background:#1a2530">
|
|
989
|
+
<strong style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#e5e7eb;font-size:13px">${escapeHtml(name)}</strong>
|
|
990
|
+
<span style="display:flex;gap:4px;align-items:center;color:#9ca3af;font-size:12px">
|
|
991
|
+
<button type="button" title="缩小" onclick="zoomBy(0.8)" style="padding:4px 9px;border:1px solid #2c3a47;border-radius:7px;color:#e5e7eb;background:transparent;font-size:12px;cursor:pointer">−</button>
|
|
992
|
+
<button type="button" title="放大" onclick="zoomBy(1.25)" style="padding:4px 9px;border:1px solid #2c3a47;border-radius:7px;color:#e5e7eb;background:transparent;font-size:12px;cursor:pointer">+</button>
|
|
993
|
+
<button type="button" title="适合宽度" onclick="zoomFit()" style="padding:4px 9px;border:1px solid #2c3a47;border-radius:7px;color:#e5e7eb;background:transparent;font-size:12px;cursor:pointer">适合</button>
|
|
994
|
+
</span>
|
|
995
|
+
<a class="btn" href="${downloadHref}" download style="padding:5px 12px;border:1px solid #2c3a47;border-radius:8px;color:#e5e7eb;text-decoration:none;font-size:13px">下载</a>
|
|
996
|
+
<button type="button" onclick="closePreview()" style="padding:5px 12px;border:1px solid #2c3a47;border-radius:8px;color:#e5e7eb;background:transparent;text-decoration:none;font-size:13px;cursor:pointer">✕ 关闭</button>
|
|
988
997
|
</div>
|
|
989
998
|
<div id="container"><div style="padding:40px;text-align:center;color:#999">加载中…</div></div>
|
|
990
999
|
<script src="${assetBase}?f=jszip.min.js"></script>
|
|
@@ -1002,6 +1011,34 @@ function closePreview() {
|
|
|
1002
1011
|
window.close();
|
|
1003
1012
|
}
|
|
1004
1013
|
const c=document.getElementById('container');
|
|
1014
|
+
// docx 按纸张固定宽度渲染,手机上屏窄。这里用 transform:scale(统一缩放,不破坏内部绝对定位
|
|
1015
|
+
// 排版,不会像 CSS zoom 那样叠字)。默认「适合宽度」整页完整显示,可放大读数。
|
|
1016
|
+
var zoom=1, fitMode=true;
|
|
1017
|
+
function dw(){
|
|
1018
|
+
// 文档页可能在 .docx-wrapper / .docx-wrap / 或直接 #container 里。取承载页面的元素;
|
|
1019
|
+
// 若直接在 #container,就包一层,避免缩放影响容器自身。
|
|
1020
|
+
var host=c.querySelector('.docx-wrapper, .docx-wrap');
|
|
1021
|
+
if(!host){ var p=c.querySelector('section.docx, .docx'); host=p? p.parentElement : c; }
|
|
1022
|
+
if(host && host===c){
|
|
1023
|
+
var wrap=document.createElement('div'); wrap.className='_dsh-docx-stage';
|
|
1024
|
+
while(c.firstChild) wrap.appendChild(c.firstChild);
|
|
1025
|
+
c.appendChild(wrap); host=wrap;
|
|
1026
|
+
}
|
|
1027
|
+
if(host){ host.style.width='max-content'; host.style.margin='0 auto'; }
|
|
1028
|
+
return host || c;
|
|
1029
|
+
}
|
|
1030
|
+
function applyZoom(){
|
|
1031
|
+
var w=dw(); if(!w) return;
|
|
1032
|
+
w.style.transformOrigin='top left';
|
|
1033
|
+
w.style.transform='scale('+zoom+')';
|
|
1034
|
+
}
|
|
1035
|
+
function zoomFit(){
|
|
1036
|
+
var page=c.querySelector('section.docx, .docx'); if(!page) return;
|
|
1037
|
+
var natW=page.offsetWidth||1; var target=c.clientWidth||1;
|
|
1038
|
+
zoom=Math.min(1, target/natW); fitMode=true; applyZoom();
|
|
1039
|
+
}
|
|
1040
|
+
function zoom100(){ zoom=1; fitMode=false; applyZoom(); }
|
|
1041
|
+
function zoomBy(f){ zoom=Math.min(8, Math.max(0.05, zoom*f)); fitMode=false; applyZoom(); }
|
|
1005
1042
|
(async()=>{
|
|
1006
1043
|
try{
|
|
1007
1044
|
const r=await fetch(${JSON.stringify(inlineHref)}, {cache:'no-store'});
|
|
@@ -1010,8 +1047,10 @@ const c=document.getElementById('container');
|
|
|
1010
1047
|
c.innerHTML='';
|
|
1011
1048
|
// styleContainer 传 null:docx-preview 用自带样式。分页靠下方 .docx-wrapper > .docx 的纸张 CSS 控制。
|
|
1012
1049
|
await docx.renderAsync(buf, c, null, {inWrapper:true, breakPages:true, ignoreLastRenderedPageBreak:false, experimental:true, className:'docx', useBase64URL:false});
|
|
1050
|
+
zoomFit(); // 默认「适合宽度」:整页等比缩放(行距/字号比例按 word 原样),可再放大读数
|
|
1013
1051
|
}catch(e){ c.innerHTML='<p style="color:#dc2626;padding:20px">渲染失败:'+(e&&e.message||e)+'</p>'; }
|
|
1014
1052
|
})();
|
|
1053
|
+
window.addEventListener('resize', function(){ try{ if(fitMode) zoomFit(); else applyZoom(); }catch(e){} });
|
|
1015
1054
|
</script>
|
|
1016
1055
|
</body></html>`);
|
|
1017
1056
|
} catch (error) {
|
|
@@ -1076,14 +1115,19 @@ const c=document.getElementById('container');
|
|
|
1076
1115
|
.bar strong{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#e5e7eb;font-size:13px}
|
|
1077
1116
|
.bar button,.bar a{padding:6px 12px;border:1px solid #2c3a47;border-radius:8px;background:transparent;color:#e5e7eb;text-decoration:none;font-size:13px;cursor:pointer;white-space:nowrap}
|
|
1078
1117
|
.bar button:disabled{opacity:.45;cursor:default}
|
|
1079
|
-
#stage{display:
|
|
1080
|
-
#stage canvas{display:block;
|
|
1118
|
+
#stage{display:block;overflow:auto;padding:20px 16px 44px;min-height:calc(100vh - 60px)}
|
|
1119
|
+
#stage canvas{display:block;margin:0 auto;background:#fff;border-radius:8px;box-shadow:0 4px 22px rgba(0,0,0,.45)}
|
|
1081
1120
|
#status{font-size:12px;color:#9ca3af;min-width:70px;text-align:center}
|
|
1082
1121
|
#msg{color:#9ca3af}
|
|
1083
1122
|
</style>
|
|
1084
1123
|
</head><body>
|
|
1085
1124
|
<div class="bar">
|
|
1086
1125
|
<strong>${escapeHtml(name)}</strong>
|
|
1126
|
+
<span style="display:flex;gap:4px;align-items:center">
|
|
1127
|
+
<button type="button" title="缩小" onclick="zoomBy(0.8)">−</button>
|
|
1128
|
+
<button type="button" title="放大" onclick="zoomBy(1.25)">+</button>
|
|
1129
|
+
<button type="button" title="适合宽度" onclick="zoomFit()">适合</button>
|
|
1130
|
+
</span>
|
|
1087
1131
|
<button type="button" id="prev" disabled>‹ 上一页</button>
|
|
1088
1132
|
<span id="status">— / —</span>
|
|
1089
1133
|
<button type="button" id="next" disabled>下一页 ›</button>
|
|
@@ -1107,6 +1151,20 @@ const prevBtn=document.getElementById('prev');
|
|
|
1107
1151
|
const nextBtn=document.getElementById('next');
|
|
1108
1152
|
const status=document.getElementById('status');
|
|
1109
1153
|
let viewer=null,total=0;
|
|
1154
|
+
var zoom=1, fitMode=true;
|
|
1155
|
+
// 幻灯片缩放:控制 canvas 的 CSS 显示尺寸等比放大/缩小(transform 对 canvas 容易叠字/错位,
|
|
1156
|
+
// 用 CSS width/height 更稳)。默认「适合宽度」看整页,可放大读数。
|
|
1157
|
+
function applyZoom(){
|
|
1158
|
+
var nw=canvas.width||1280, nh=canvas.height||720;
|
|
1159
|
+
canvas.style.width=Math.round(nw*zoom)+'px';
|
|
1160
|
+
canvas.style.height=Math.round(nh*zoom)+'px';
|
|
1161
|
+
}
|
|
1162
|
+
function zoomFit(){
|
|
1163
|
+
var nw=canvas.width||1280; var t=stage.clientWidth||1;
|
|
1164
|
+
zoom=Math.min(1, t/nw); fitMode=true; applyZoom();
|
|
1165
|
+
}
|
|
1166
|
+
function zoom100(){ zoom=1; fitMode=false; applyZoom(); }
|
|
1167
|
+
function zoomBy(f){ zoom=Math.min(2,Math.max(0.05,zoom*f)); fitMode=false; applyZoom(); }
|
|
1110
1168
|
function update(){
|
|
1111
1169
|
if(!viewer)return;
|
|
1112
1170
|
const cur=viewer.getCurrentSlideIndex();
|
|
@@ -1121,12 +1179,13 @@ function update(){
|
|
|
1121
1179
|
const blob=await r.blob();
|
|
1122
1180
|
msg.style.display='none';
|
|
1123
1181
|
canvas.style.display='block';
|
|
1124
|
-
// 给一个确定的初始尺寸,确保库能正常渲染;显示由 CSS
|
|
1125
|
-
canvas.width=
|
|
1182
|
+
// 给一个确定的初始尺寸,确保库能正常渲染;显示由 CSS 缩放(分辨率取高些,放大时更清晰)
|
|
1183
|
+
canvas.width=1920; canvas.height=1080;
|
|
1126
1184
|
viewer=new window.PptxViewJS.PPTXViewer({canvas});
|
|
1127
1185
|
await viewer.loadFile(new File([blob],${JSON.stringify(name)},{type:'application/vnd.openxmlformats-officedocument.presentationml.presentation'}));
|
|
1128
1186
|
await viewer.render();
|
|
1129
1187
|
total=viewer.getSlideCount();
|
|
1188
|
+
zoomFit();
|
|
1130
1189
|
update();
|
|
1131
1190
|
}catch(e){
|
|
1132
1191
|
msg.style.display='';
|
|
@@ -1136,6 +1195,7 @@ function update(){
|
|
|
1136
1195
|
})();
|
|
1137
1196
|
prevBtn.addEventListener('click',async()=>{if(viewer){await viewer.previousSlide();update();}});
|
|
1138
1197
|
nextBtn.addEventListener('click',async()=>{if(viewer){await viewer.nextSlide();update();}});
|
|
1198
|
+
window.addEventListener('resize',function(){ try{ if(fitMode) zoomFit(); else applyZoom(); }catch(e){} });
|
|
1139
1199
|
</script>
|
|
1140
1200
|
</body></html>`);
|
|
1141
1201
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-long-plugins",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "Merged DSH web plugins: upload manager (drag-and-drop attach any file to the message), workspace output files, skill docs, account balance, Markdown-to-Word (md2docx), polished file preview,
|
|
3
|
+
"version": "1.3.4",
|
|
4
|
+
"description": "Merged DSH web plugins: upload manager (drag-and-drop attach any file to the message), workspace output files, skill docs, account balance, Markdown-to-Word (md2docx), and polished file preview (Word & PowerPoint real preview with zoom/pan, rendered Markdown), plus an auto-repair install for DSH core patches (reverse-proxy WebSocket heartbeat, upgrade relink). | 一个插件整合 DSH Web 的常用增强:上传管理(拖放上传:拖任意文件到会话框直接附加)、工作区「输出文件」面板、技能文档浏览、账户余额显示、Markdown 转 Word(md2docx)、Word/PowerPoint 真实预览(可缩放、翻页);并自带修复安装,自动重连 DSH 核心补丁(反代 WebSocket 心跳、升级重连)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "lib/index.js",
|