dsh-live2dwaifu 1.2.0 → 1.2.2
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 +11 -0
- package/assets/corpus.html +47 -31
- package/assets/persona.html +33 -17
- package/assets/tone.html +34 -18
- package/lib/client.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -380,6 +380,17 @@ curl -X POST http://127.0.0.1:<端口>/dsh-live2d/api/push \
|
|
|
380
380
|
|
|
381
381
|
版本号怎么走:动了功能和结构就抬第二位(1.2.0),只补洞和小修就抬第三位(1.2.1)。
|
|
382
382
|
|
|
383
|
+
### 1.2.2
|
|
384
|
+
|
|
385
|
+
- 人设卡、音色、语料三个页面的按钮和说明改成通用说法:保存/追加保存/覆盖保存/放弃修改/选择文件/播放/关掉。
|
|
386
|
+
- 状态提示统一成「读取中/已读取/保存中/已保存/保存失败」,不再出现「读…」「存好了」这种。
|
|
387
|
+
- 语料页的示例和解析结果里,标签从「他/你」换成「对方/角色」。
|
|
388
|
+
|
|
389
|
+
### 1.2.1
|
|
390
|
+
|
|
391
|
+
- 人设卡、音色、语料三个页面右上角各加了一个「关掉」。之前只能点外层那条栏上的按钮,页面本身没出口。
|
|
392
|
+
- 外层那条栏的按钮改成「× 关掉」,更好认。
|
|
393
|
+
|
|
383
394
|
### 1.2.0
|
|
384
395
|
|
|
385
396
|
- 语料吃的文件多了:`.md`、`.csv`、`.srt`、`.vtt`、`.ass`。字幕会自动去掉序号、时间轴和样式标签。
|
package/assets/corpus.html
CHANGED
|
@@ -37,37 +37,43 @@
|
|
|
37
37
|
.tips { color:#6f7783; font-size:11.5px; line-height:1.8; margin-top:10px; }
|
|
38
38
|
code { background:rgba(255,255,255,.06); border-radius:4px; padding:1px 5px; font-size:11px; }
|
|
39
39
|
.state { color:var(--dim); font-size:11.5px; margin-left:auto; }
|
|
40
|
+
|
|
41
|
+
.sheet-close { position: fixed; right: 18px; top: 14px; z-index: 20;
|
|
42
|
+
padding: 7px 14px; border-radius: 9px; border: 1px solid rgba(255,255,255,.16);
|
|
43
|
+
background: rgba(30,36,45,.92); color: #dfe4ec; font: inherit; font-size: 12px;
|
|
44
|
+
cursor: pointer; backdrop-filter: blur(6px); }
|
|
45
|
+
.sheet-close:hover { background: rgba(46,55,68,.96); }
|
|
40
46
|
</style>
|
|
41
47
|
</head>
|
|
42
48
|
<body>
|
|
43
49
|
|
|
44
50
|
<h1>语料</h1>
|
|
45
|
-
<p class="sub"
|
|
51
|
+
<p class="sub">导入角色说过的话,作为生成回复时的语气参考。不要求格式整齐,能解析即可。</p>
|
|
46
52
|
|
|
47
53
|
<div class="row">
|
|
48
54
|
<select id="models"></select>
|
|
49
55
|
<div class="btns">
|
|
50
|
-
<button class="act" id="pick"
|
|
51
|
-
<button class="act primary" id="append"
|
|
52
|
-
<button class="act" id="replace"
|
|
56
|
+
<button class="act" id="pick">选择文件</button>
|
|
57
|
+
<button class="act primary" id="append">追加保存</button>
|
|
58
|
+
<button class="act" id="replace">覆盖保存</button>
|
|
53
59
|
</div>
|
|
54
60
|
<span class="state" id="state"></span>
|
|
55
61
|
</div>
|
|
56
62
|
|
|
57
63
|
<div class="cols">
|
|
58
64
|
<div class="col box">
|
|
59
|
-
<h2
|
|
60
|
-
<textarea id="raw" spellcheck="false" placeholder="
|
|
65
|
+
<h2>粘贴文本</h2>
|
|
66
|
+
<textarea id="raw" spellcheck="false" placeholder="直接粘贴,支持以下几种写法:
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
对方:今天忙吗
|
|
69
|
+
角色:刚坐下,手还是湿的。
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
或者只粘贴角色台词,一行一句:
|
|
72
|
+
刚坐下,手还是湿的。
|
|
73
|
+
水在桌上。
|
|
68
74
|
|
|
69
|
-
|
|
70
|
-
<div id="drop"
|
|
75
|
+
也支持带引号的一句:「嗯,我也是。」"></textarea>
|
|
76
|
+
<div id="drop">拖放文件到此处,或点击选择文件(支持多选)<br /><span style="font-size:11px">支持文本、字幕、表格;图片与视频见下方说明</span></div>
|
|
71
77
|
<input id="files" type="file" multiple accept=".txt,.json,.jsonl,.csv,.md,.srt,.vtt,.ass,image/*,video/*" style="display:none" />
|
|
72
78
|
<div class="tips">
|
|
73
79
|
认得的写法:<code>对方:… / 角色:…</code>、<code>「…」</code>、<code>- …</code>、一行一句、
|
|
@@ -78,8 +84,8 @@
|
|
|
78
84
|
</div>
|
|
79
85
|
|
|
80
86
|
<div class="col box">
|
|
81
|
-
<h2
|
|
82
|
-
<div class="stat" id="stat"
|
|
87
|
+
<h2>解析结果</h2>
|
|
88
|
+
<div class="stat" id="stat">暂无内容</div>
|
|
83
89
|
<div id="preview"></div>
|
|
84
90
|
<div class="tips" id="saved"></div>
|
|
85
91
|
</div>
|
|
@@ -162,10 +168,10 @@
|
|
|
162
168
|
box.innerHTML = '';
|
|
163
169
|
var show = [];
|
|
164
170
|
for (var i = 0; i < parsed.pairs.length && show.length < 8; i += 1) {
|
|
165
|
-
show.push('
|
|
171
|
+
show.push('对方:' + parsed.pairs[i].user + '<br>角色:' + parsed.pairs[i].assistant);
|
|
166
172
|
}
|
|
167
173
|
for (var j = 0; j < parsed.lines.length && show.length < 14; j += 1) {
|
|
168
|
-
show.push('
|
|
174
|
+
show.push('角色:' + parsed.lines[j]);
|
|
169
175
|
}
|
|
170
176
|
show.forEach(function (html) {
|
|
171
177
|
var d = document.createElement('div');
|
|
@@ -185,15 +191,15 @@
|
|
|
185
191
|
|
|
186
192
|
function load() {
|
|
187
193
|
if (!modelId) return;
|
|
188
|
-
$('state').textContent = '
|
|
194
|
+
$('state').textContent = '读取中';
|
|
189
195
|
fetch('/dsh-live2d/api/corpus?id=' + encodeURIComponent(modelId))
|
|
190
196
|
.then(function (r) { return r.json(); })
|
|
191
197
|
.then(function (d) {
|
|
192
198
|
stored = { lines: d.lines || [], pairs: d.pairs || [] };
|
|
193
|
-
$('state').textContent = '
|
|
199
|
+
$('state').textContent = '已读取';
|
|
194
200
|
render();
|
|
195
201
|
})
|
|
196
|
-
.catch(function (e) { $('state').textContent = '
|
|
202
|
+
.catch(function (e) { $('state').textContent = '读取失败:' + e.message; });
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
function save(mode) {
|
|
@@ -208,10 +214,10 @@
|
|
|
208
214
|
};
|
|
209
215
|
}
|
|
210
216
|
if (!payload.lines.length && !payload.pairs.length) {
|
|
211
|
-
$('state').textContent = '
|
|
217
|
+
$('state').textContent = '没有可保存的内容';
|
|
212
218
|
return;
|
|
213
219
|
}
|
|
214
|
-
$('state').textContent = '
|
|
220
|
+
$('state').textContent = '保存中';
|
|
215
221
|
fetch('/dsh-live2d/api/corpus', {
|
|
216
222
|
method: 'POST',
|
|
217
223
|
headers: { 'content-type': 'application/json' },
|
|
@@ -219,13 +225,13 @@
|
|
|
219
225
|
})
|
|
220
226
|
.then(function (r) { return r.json(); })
|
|
221
227
|
.then(function (d) {
|
|
222
|
-
if (!d.ok) { $('state').textContent = '
|
|
223
|
-
$('state').textContent = '
|
|
228
|
+
if (!d.ok) { $('state').textContent = '保存失败:' + (d.error || '未知错误'); return; }
|
|
229
|
+
$('state').textContent = '已保存,共 ' + d.total + ' 条';
|
|
224
230
|
$('raw').value = '';
|
|
225
231
|
files = [];
|
|
226
232
|
load();
|
|
227
233
|
})
|
|
228
|
-
.catch(function (e) { $('state').textContent = '
|
|
234
|
+
.catch(function (e) { $('state').textContent = '保存失败:' + e.message; });
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
$('raw').addEventListener('input', reparse);
|
|
@@ -256,17 +262,17 @@
|
|
|
256
262
|
texts.push(f);
|
|
257
263
|
});
|
|
258
264
|
if (skipped.length) {
|
|
259
|
-
$('saved').textContent = '
|
|
265
|
+
$('saved').textContent = '未读取:' + skipped.join('、') + '。图片可留作形象参考;视频请先导出字幕(.srt)或直接粘贴台词。';
|
|
260
266
|
}
|
|
261
|
-
if (!texts.length) { $('state').textContent = '
|
|
262
|
-
$('state').textContent = '
|
|
267
|
+
if (!texts.length) { $('state').textContent = '没有可读取的文本文件'; return; }
|
|
268
|
+
$('state').textContent = '正在读取文件';
|
|
263
269
|
var left = texts.length;
|
|
264
270
|
texts.forEach(function (f) {
|
|
265
271
|
var reader = new FileReader();
|
|
266
272
|
reader.onload = function () {
|
|
267
273
|
files.push(String(reader.result || ''));
|
|
268
274
|
left -= 1;
|
|
269
|
-
if (left === 0) { $('state').textContent = '
|
|
275
|
+
if (left === 0) { $('state').textContent = '已读取 ' + texts.length + ' 个文件'; reparse(); }
|
|
270
276
|
};
|
|
271
277
|
reader.onerror = function () { left -= 1; if (left === 0) reparse(); };
|
|
272
278
|
reader.readAsText(f, 'utf-8');
|
|
@@ -299,10 +305,10 @@
|
|
|
299
305
|
});
|
|
300
306
|
modelId = d.selected || (list[0] && list[0].id) || '';
|
|
301
307
|
if (modelId) sel.value = modelId;
|
|
302
|
-
if (!list.length) { $('state').textContent = '
|
|
308
|
+
if (!list.length) { $('state').textContent = '尚未导入模型'; return; }
|
|
303
309
|
load();
|
|
304
310
|
})
|
|
305
|
-
.catch(function (e) { $('state').textContent = '
|
|
311
|
+
.catch(function (e) { $('state').textContent = '读取模型列表失败:' + e.message; });
|
|
306
312
|
|
|
307
313
|
$('models').addEventListener('change', function (e) {
|
|
308
314
|
modelId = e.target.value;
|
|
@@ -310,5 +316,15 @@
|
|
|
310
316
|
});
|
|
311
317
|
})();
|
|
312
318
|
</script>
|
|
319
|
+
<button id="sheet-close" class="sheet-close">关掉</button>
|
|
320
|
+
|
|
321
|
+
<script>
|
|
322
|
+
(function () {
|
|
323
|
+
var b = document.getElementById('sheet-close');
|
|
324
|
+
if (b) b.onclick = function () {
|
|
325
|
+
try { window.parent.postMessage({ type: 'dsh-live2d/close' }, '*'); } catch (e) {}
|
|
326
|
+
};
|
|
327
|
+
})();
|
|
328
|
+
</script>
|
|
313
329
|
</body>
|
|
314
330
|
</html>
|
package/assets/persona.html
CHANGED
|
@@ -35,26 +35,32 @@
|
|
|
35
35
|
button.act:hover { filter:brightness(1.12); }
|
|
36
36
|
.state { color:var(--dim); font-size:11px; margin-left:auto; }
|
|
37
37
|
.tip { color:#6f7783; font-size:11px; margin-top:10px; line-height:1.7; }
|
|
38
|
+
|
|
39
|
+
.sheet-close { position: fixed; right: 18px; top: 14px; z-index: 20;
|
|
40
|
+
padding: 7px 14px; border-radius: 9px; border: 1px solid rgba(255,255,255,.16);
|
|
41
|
+
background: rgba(30,36,45,.92); color: #dfe4ec; font: inherit; font-size: 12px;
|
|
42
|
+
cursor: pointer; backdrop-filter: blur(6px); }
|
|
43
|
+
.sheet-close:hover { background: rgba(46,55,68,.96); }
|
|
38
44
|
</style>
|
|
39
45
|
</head>
|
|
40
46
|
<body>
|
|
41
47
|
|
|
42
48
|
<div class="left">
|
|
43
49
|
<div class="card"><iframe id="live" src="/dsh-live2d/viewer?embed=1"></iframe></div>
|
|
44
|
-
<div class="tip"
|
|
50
|
+
<div class="tip">左侧是当前模型预览。保存后,下一次回答就会按新的设定生成。</div>
|
|
45
51
|
</div>
|
|
46
52
|
|
|
47
53
|
<div class="panel">
|
|
48
54
|
<h1>人设卡</h1>
|
|
49
|
-
<p class="sub"
|
|
55
|
+
<p class="sub">角色的身份、性格、说话方式,都写在这里。</p>
|
|
50
56
|
|
|
51
57
|
<div class="group">
|
|
52
|
-
<h2
|
|
58
|
+
<h2>目标模型</h2>
|
|
53
59
|
<select id="models"></select>
|
|
54
60
|
</div>
|
|
55
61
|
|
|
56
62
|
<div class="group">
|
|
57
|
-
<h2
|
|
63
|
+
<h2>角色设定</h2>
|
|
58
64
|
<textarea id="persona" spellcheck="false"></textarea>
|
|
59
65
|
</div>
|
|
60
66
|
|
|
@@ -63,18 +69,18 @@
|
|
|
63
69
|
<label class="switch">
|
|
64
70
|
<input type="checkbox" id="isolation" checked />
|
|
65
71
|
<span>
|
|
66
|
-
<b
|
|
67
|
-
<em
|
|
72
|
+
<b>角色视角隔离</b>
|
|
73
|
+
<em>打开后,角色不会提到程序、界面、插件、模型这些词,按设定世界的视角回答。关闭后角色会承认自己是插件里的角色。</em>
|
|
68
74
|
</span>
|
|
69
75
|
</label>
|
|
70
76
|
</div>
|
|
71
77
|
|
|
72
78
|
<div class="foot">
|
|
73
|
-
<button class="act primary" id="save"
|
|
74
|
-
<button class="act" id="reload"
|
|
79
|
+
<button class="act primary" id="save">保存</button>
|
|
80
|
+
<button class="act" id="reload">放弃修改</button>
|
|
75
81
|
<span class="state" id="state"></span>
|
|
76
82
|
</div>
|
|
77
|
-
<div class="tip"
|
|
83
|
+
<div class="tip">保存在 <code>~/.dsh/dsh-live2d/models/<id>/meta.json</code> 的 <code>persona</code> 字段,也可以直接编辑该文件。</div>
|
|
78
84
|
</div>
|
|
79
85
|
|
|
80
86
|
<script>
|
|
@@ -90,20 +96,20 @@
|
|
|
90
96
|
|
|
91
97
|
function load() {
|
|
92
98
|
if (!modelId) return;
|
|
93
|
-
state.textContent = '
|
|
99
|
+
state.textContent = '读取中';
|
|
94
100
|
fetch('/dsh-live2d/api/persona?id=' + encodeURIComponent(modelId))
|
|
95
101
|
.then(function (r) { return r.json(); })
|
|
96
102
|
.then(function (d) {
|
|
97
103
|
area.value = d.persona || '';
|
|
98
104
|
iso.checked = d.isolation !== false;
|
|
99
|
-
state.textContent = d.custom ? '
|
|
105
|
+
state.textContent = d.custom ? '已自定义' : '使用默认设定';
|
|
100
106
|
})
|
|
101
|
-
.catch(function (e) { state.textContent = '
|
|
107
|
+
.catch(function (e) { state.textContent = '读取失败:' + e.message; });
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
function save() {
|
|
105
111
|
if (!modelId) return;
|
|
106
|
-
state.textContent = '
|
|
112
|
+
state.textContent = '保存中';
|
|
107
113
|
fetch('/dsh-live2d/api/persona', {
|
|
108
114
|
method: 'POST',
|
|
109
115
|
headers: { 'content-type': 'application/json' },
|
|
@@ -111,12 +117,12 @@
|
|
|
111
117
|
})
|
|
112
118
|
.then(function (r) { return r.json(); })
|
|
113
119
|
.then(function (d) {
|
|
114
|
-
state.textContent = d.ok ? '
|
|
120
|
+
state.textContent = d.ok ? '已保存' : '保存失败:' + (d.error || '未知错误');
|
|
115
121
|
if (d.ok) {
|
|
116
122
|
frame.src = '/dsh-live2d/viewer?embed=1&t=' + Date.now();
|
|
117
123
|
}
|
|
118
124
|
})
|
|
119
|
-
.catch(function (e) { state.textContent = '
|
|
125
|
+
.catch(function (e) { state.textContent = '保存失败:' + e.message; });
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
$('save').addEventListener('click', save);
|
|
@@ -139,10 +145,20 @@
|
|
|
139
145
|
});
|
|
140
146
|
modelId = d.selected || (list[0] && list[0].id) || '';
|
|
141
147
|
if (modelId) sel.value = modelId;
|
|
142
|
-
if (!list.length) { state.textContent = '
|
|
148
|
+
if (!list.length) { state.textContent = '尚未导入模型'; return; }
|
|
143
149
|
load();
|
|
144
150
|
})
|
|
145
|
-
.catch(function (e) { state.textContent = '
|
|
151
|
+
.catch(function (e) { state.textContent = '读取模型列表失败:' + e.message; });
|
|
152
|
+
})();
|
|
153
|
+
</script>
|
|
154
|
+
<button id="sheet-close" class="sheet-close">关掉</button>
|
|
155
|
+
|
|
156
|
+
<script>
|
|
157
|
+
(function () {
|
|
158
|
+
var b = document.getElementById('sheet-close');
|
|
159
|
+
if (b) b.onclick = function () {
|
|
160
|
+
try { window.parent.postMessage({ type: 'dsh-live2d/close' }, '*'); } catch (e) {}
|
|
161
|
+
};
|
|
146
162
|
})();
|
|
147
163
|
</script>
|
|
148
164
|
</body>
|
package/assets/tone.html
CHANGED
|
@@ -38,26 +38,32 @@
|
|
|
38
38
|
.foot { display:flex; align-items:center; gap:10px; }
|
|
39
39
|
.state { color:var(--dim); font-size:11px; margin-left:auto; }
|
|
40
40
|
.tip { color:#6f7783; font-size:11px; margin-top:10px; line-height:1.7; }
|
|
41
|
+
|
|
42
|
+
.sheet-close { position: fixed; right: 18px; top: 14px; z-index: 20;
|
|
43
|
+
padding: 7px 14px; border-radius: 9px; border: 1px solid rgba(255,255,255,.16);
|
|
44
|
+
background: rgba(30,36,45,.92); color: #dfe4ec; font: inherit; font-size: 12px;
|
|
45
|
+
cursor: pointer; backdrop-filter: blur(6px); }
|
|
46
|
+
.sheet-close:hover { background: rgba(46,55,68,.96); }
|
|
41
47
|
</style>
|
|
42
48
|
</head>
|
|
43
49
|
<body>
|
|
44
50
|
|
|
45
51
|
<div class="left">
|
|
46
52
|
<div class="card"><iframe id="live" src="/dsh-live2d/viewer?embed=1"></iframe></div>
|
|
47
|
-
<div class="tip"
|
|
53
|
+
<div class="tip">没有声音时,先点击一次页面——浏览器要求先有用户操作才允许播放。</div>
|
|
48
54
|
</div>
|
|
49
55
|
|
|
50
56
|
<div class="panel">
|
|
51
|
-
<h1
|
|
52
|
-
<p class="sub"
|
|
57
|
+
<h1>声音</h1>
|
|
58
|
+
<p class="sub">每说一个字发一声短音。音量调到 0 即静音,只保留文字和口型。</p>
|
|
53
59
|
|
|
54
60
|
<div class="group">
|
|
55
|
-
<h2
|
|
61
|
+
<h2>目标模型</h2>
|
|
56
62
|
<select id="models"></select>
|
|
57
63
|
</div>
|
|
58
64
|
|
|
59
65
|
<div class="group">
|
|
60
|
-
<h2
|
|
66
|
+
<h2>音色预设</h2>
|
|
61
67
|
<div class="presets" id="presets">
|
|
62
68
|
<button data-p="soft" class="on">柔和</button>
|
|
63
69
|
<button data-p="crisp">清脆</button>
|
|
@@ -76,19 +82,19 @@
|
|
|
76
82
|
</div>
|
|
77
83
|
|
|
78
84
|
<div class="group">
|
|
79
|
-
<h2
|
|
85
|
+
<h2>试听</h2>
|
|
80
86
|
<div class="typebox">
|
|
81
87
|
<input id="text" value="窗台那盆,红了。" />
|
|
82
|
-
<button class="act primary" id="say"
|
|
88
|
+
<button class="act primary" id="say">播放</button>
|
|
83
89
|
</div>
|
|
84
90
|
</div>
|
|
85
91
|
|
|
86
92
|
<div class="foot">
|
|
87
|
-
<button class="act primary" id="save"
|
|
93
|
+
<button class="act primary" id="save">保存</button>
|
|
88
94
|
<button class="act" id="reset">恢复默认</button>
|
|
89
95
|
<span class="state" id="state"></span>
|
|
90
96
|
</div>
|
|
91
|
-
<div class="tip"
|
|
97
|
+
<div class="tip">每只模型单独保存一份音色设置。</div>
|
|
92
98
|
</div>
|
|
93
99
|
|
|
94
100
|
<script>
|
|
@@ -179,12 +185,12 @@
|
|
|
179
185
|
voice = Object.assign({}, DEFAULTS);
|
|
180
186
|
show();
|
|
181
187
|
pushTone();
|
|
182
|
-
state.textContent = '
|
|
188
|
+
state.textContent = '已恢复默认值,尚未保存';
|
|
183
189
|
});
|
|
184
190
|
|
|
185
191
|
$('save').addEventListener('click', function () {
|
|
186
192
|
if (!modelId) return;
|
|
187
|
-
state.textContent = '
|
|
193
|
+
state.textContent = '保存中';
|
|
188
194
|
fetch('/dsh-live2d/api/voice', {
|
|
189
195
|
method: 'POST',
|
|
190
196
|
headers: { 'content-type': 'application/json' },
|
|
@@ -192,9 +198,9 @@
|
|
|
192
198
|
})
|
|
193
199
|
.then(function (r) { return r.json(); })
|
|
194
200
|
.then(function (d) {
|
|
195
|
-
state.textContent = d.ok ? '
|
|
201
|
+
state.textContent = d.ok ? '已保存' : '保存失败:' + (d.error || '未知错误');
|
|
196
202
|
})
|
|
197
|
-
.catch(function (e) { state.textContent = '
|
|
203
|
+
.catch(function (e) { state.textContent = '保存失败:' + e.message; });
|
|
198
204
|
});
|
|
199
205
|
|
|
200
206
|
sel.addEventListener('change', function () {
|
|
@@ -204,7 +210,7 @@
|
|
|
204
210
|
|
|
205
211
|
function loadVoice(alsoSwitch) {
|
|
206
212
|
if (!modelId) return;
|
|
207
|
-
state.textContent = '
|
|
213
|
+
state.textContent = '读取中';
|
|
208
214
|
if (alsoSwitch) {
|
|
209
215
|
fetch('/dsh-live2d/api/select', {
|
|
210
216
|
method: 'POST',
|
|
@@ -221,9 +227,9 @@
|
|
|
221
227
|
show();
|
|
222
228
|
pushTone();
|
|
223
229
|
setTimeout(pushTone, 900);
|
|
224
|
-
state.textContent = '
|
|
230
|
+
state.textContent = '已读取';
|
|
225
231
|
})
|
|
226
|
-
.catch(function (e) { state.textContent = '
|
|
232
|
+
.catch(function (e) { state.textContent = '读取失败:' + e.message; });
|
|
227
233
|
}
|
|
228
234
|
|
|
229
235
|
fetch('/dsh-live2d/api/models')
|
|
@@ -240,17 +246,27 @@
|
|
|
240
246
|
modelId = d.selected || (list[0] && list[0].id) || '';
|
|
241
247
|
if (modelId) sel.value = modelId;
|
|
242
248
|
if (!list.length) {
|
|
243
|
-
state.textContent = '
|
|
249
|
+
state.textContent = '尚未导入模型';
|
|
244
250
|
return;
|
|
245
251
|
}
|
|
246
252
|
loadVoice(false);
|
|
247
253
|
})
|
|
248
|
-
.catch(function (e) { state.textContent = '
|
|
254
|
+
.catch(function (e) { state.textContent = '读取模型列表失败:' + e.message; });
|
|
249
255
|
|
|
250
256
|
frame.addEventListener('load', function () {
|
|
251
257
|
pushTone();
|
|
252
258
|
});
|
|
253
259
|
})();
|
|
254
260
|
</script>
|
|
261
|
+
<button id="sheet-close" class="sheet-close">关掉</button>
|
|
262
|
+
|
|
263
|
+
<script>
|
|
264
|
+
(function () {
|
|
265
|
+
var b = document.getElementById('sheet-close');
|
|
266
|
+
if (b) b.onclick = function () {
|
|
267
|
+
try { window.parent.postMessage({ type: 'dsh-live2d/close' }, '*'); } catch (e) {}
|
|
268
|
+
};
|
|
269
|
+
})();
|
|
270
|
+
</script>
|
|
255
271
|
</body>
|
|
256
272
|
</html>
|
package/lib/client.js
CHANGED
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
const onMsg = (e) => {
|
|
102
102
|
const d = e.data || {};
|
|
103
103
|
if (d.type === 'dsh-live2d/open' && d.sheet) setSheet(String(d.sheet));
|
|
104
|
+
if (d.type === 'dsh-live2d/close') setSheet(null);
|
|
104
105
|
};
|
|
105
106
|
window.addEventListener('message', onMsg);
|
|
106
107
|
return () => window.removeEventListener('message', onMsg);
|
|
@@ -265,7 +266,7 @@
|
|
|
265
266
|
'div',
|
|
266
267
|
{ className: 'dsh-l2d-sheet-bar' },
|
|
267
268
|
h('span', null, SHEET_TITLE[sheet] || sheet),
|
|
268
|
-
h('button', { onClick: () => setSheet(null) }, '关掉'),
|
|
269
|
+
h('button', { onClick: () => setSheet(null) }, '× 关掉'),
|
|
269
270
|
),
|
|
270
271
|
h('iframe', { className: 'dsh-l2d-sheet-body', src: BASE + '/' + sheet }),
|
|
271
272
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-live2dwaifu",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "给 DSH 网页右下角请一个 Live2D 角色:会眨眼、会呼吸、视线跟着鼠标、点她有反应、说话时嘴动、心情变了眉毛跟着动。模型不用内置——谁装谁放自己的文件夹;支持自定义 .exp3.json 表情和 .motion3.json 动作,卡片能拖能缩,背景可换。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|