efront 4.33.3 → 4.34.0

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.
@@ -40,6 +40,18 @@
40
40
  - zh-CN: 禁用
41
41
  en: Disable
42
42
 
43
+ - zh-CN: 复制失败!
44
+ en: Copy failed!
45
+
46
+ - zh-CN: 允许
47
+ en: allow
48
+
49
+ - zh-CN: 不允许
50
+ en: not allowed
51
+
52
+ - zh-CN: 是否允许来自$1($2)的公网会话?
53
+ en: Will you allow public network sessions from $1 ($2)?
54
+
43
55
  - zh-CN: 压缩算法不支持
44
56
  en: Compression algorithm not supported
45
57
 
package/apps/_index.html CHANGED
@@ -1,10 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <!--
3
3
  http://efront.cc
4
- 乌鸦不是钟楼燕
5
- 筑巢不下尖尾檐
6
- 雨打风摇三冬寒
7
- 不去南方不需还
4
+ 没有有效限制措施的条文不是法律,而是愚弄民众的说辞。
8
5
  -->
9
6
  <html lang="zh-CN">
10
7
 
@@ -3,7 +3,7 @@ async function link(id, page) {
3
3
  id = await data.from("link");
4
4
  }
5
5
  if (!page.name) $scoped.get(page).title = `会话窗口(<span nodrag>${id}</span>)`;
6
- page.roomid = id;
6
+ page.clientid = id;
7
7
  var removed = false;
8
8
  on("remove")(page, function () {
9
9
  removed = true;
@@ -21,8 +21,8 @@ function main(params) {
21
21
  else id = params;
22
22
  var page = frame$chat(name);
23
23
  if (name) page.name = name;
24
- care(page, 'send', function (msg) {
25
- data.from("cast", { id: page.roomid, msg });
24
+ care(page, 'send', function ([sendto, msg]) {
25
+ data.from("cast", { id: sendto, msg });
26
26
  });
27
27
  link(id, page);
28
28
  return page;
@@ -19,7 +19,7 @@
19
19
  ${i18n`自动刷新`}
20
20
  </span>
21
21
  <swap -model="autoreload"></swap>
22
- <btn @click="chat()">${i18n`新建连接`}</btn>
22
+ <!-- <btn @click="chat()">${i18n`新建连接`}</btn> -->
23
23
  </div>
24
24
  <div class="clusters">
25
25
  <a -repeat="(c,i) in clusters" ng-class="{current:i===index.index}" @click="active(i,c)">
@@ -1,24 +1,29 @@
1
1
  var Symbol = this.Symbol || function () {
2
+ var symbolid = 0;
2
3
  function Symbol(a) {
3
- if (this instanceof Symbol) {
4
- this.symbol = String(a);
4
+ this.id = ++symbolid;
5
+ this.name = String(a);
6
+ }
7
+ function Symbol1(a) {
8
+ if (this instanceof Symbol1) {
9
+ throw new Error('Symbol不是构造方法!');
5
10
  } else if (a instanceof Symbol) {
6
- return a;
11
+ throw new Error('无法将Symbol类型转换成字符串!');
7
12
  } else {
8
13
  return new Symbol(a);
9
14
  }
10
15
  }
11
16
  var prototype = new Symbol;
12
17
  prototype.toString = function () {
13
- return 'Symbol(' + this.symbol + ")";
18
+ return `Symbol(${this.name}/${this.id})`;
14
19
  };
15
20
  prototype.valueOf = function () {
16
21
  return this;
17
22
  };
18
23
 
19
24
  Symbol.prototype = prototype;
20
- Symbol.iterator = Symbol('iterator');
21
- Symbol.asyncIterator = Symbol('asyncIterator');
25
+ Symbol.iterator = Symbol1('iterator');
26
+ Symbol.asyncIterator = Symbol1('asyncIterator');
22
27
  var iterator = function () {
23
28
  var arr = this, cx = 0;
24
29
  return {
@@ -33,5 +38,5 @@ var Symbol = this.Symbol || function () {
33
38
  } catch {
34
39
  Array.prototype[Symbol.iterator] = iterator;
35
40
  }
36
- return Symbol;
41
+ return Symbol1;
37
42
  }();
@@ -56,11 +56,12 @@ var createRefId = function (o) {
56
56
  return ids.join('');
57
57
  }
58
58
  var ignore = Symbol("ignore");
59
+ var mapkey = null;
59
60
  var maplist = function (u) {
60
61
  var map = Object.create(null);
61
62
  for (var o of u) {
62
- if (o.maped) continue;
63
- o.maped = true;
63
+ if (o[mapkey]) continue;
64
+ o[mapkey] = true;
64
65
  var r = createRefId(o);
65
66
  if (!map[r]) {
66
67
  map[r] = [];
@@ -180,7 +181,21 @@ function inCondition(o) {
180
181
  return incondition;
181
182
 
182
183
  }
183
-
184
+ var noVarOutOfFor = function (os, qq, sb, su) {
185
+ if (qq === sb) return true;
186
+ if (enumtype & REFMOVE) return false;
187
+ var [o] = os;
188
+ var us = su[o.tack];
189
+ if (!us) return false;
190
+ var otext = o.text;
191
+ var c = 0;
192
+ for (var u of us) {
193
+ if (u.text === otext) {
194
+ c++;
195
+ }
196
+ }
197
+ return c === os.length;
198
+ };
184
199
  function enumref(refitem, scoped) {
185
200
  if (enumtype === REFMOVE) {
186
201
  var c = 0;
@@ -204,7 +219,7 @@ function enumref(refitem, scoped) {
204
219
  if (o.queue.kind) break;
205
220
  var q = o.queue;
206
221
  if (q !== scoped.body) {
207
- if (q.entry === '(' && q.queue === scoped.body) {
222
+ if (q.entry === '(' && noVarOutOfFor(os, q.queue, scoped.body, scoped.used)) {
208
223
  var qp = q.prev;
209
224
  if (qp?.type === EXPRESS) qp = qp.prev;
210
225
  if (qp && qp.type === STRAP && qp.text === "await") qp = qp.prev;
@@ -285,10 +300,16 @@ function enumref(refitem, scoped) {
285
300
  }
286
301
  function atuoenum(scoped) {
287
302
  var { used, caps } = scoped;
303
+ mapkey = Symbol('enumed');
288
304
  for (var k in caps) {
289
305
  var rs = maplist(used[k]);
290
306
  enumref(rs, scoped);
291
307
  }
308
+ for (var k in caps) {
309
+ for (var o of used[k]) {
310
+ delete o[mapkey];
311
+ }
312
+ }
292
313
  }
293
314
  var enumtype = 0;
294
315
  var exports = module.exports = function main(code, type = REFMOVE) {
@@ -1,7 +1,7 @@
1
1
  var scanner2 = require("./scanner2");
2
2
  var strings = require("../basic/strings");
3
3
  var Program = scanner2.Program;
4
- var { STAMP, SCOPED, STRAP, EXPRESS, pickAssignment, COMMENT, SPACE, PROPERTY, VALUE, LABEL, QUOTED, snapExpressFoot, isEval, canbeTemp, rename, isHalfSentence, skipFunction, getDeclared, skipAssignment, skipSentenceQueue, createScoped, createString, splice, relink, rolink, pickSentence, snapExpressHead, needBreakBetween } = require("./common");
4
+ var { STAMP, SCOPED, STRAP, EXPRESS, mergeTo, pickAssignment, COMMENT, SPACE, PROPERTY, VALUE, LABEL, QUOTED, snapExpressFoot, isEval, canbeTemp, rename, isHalfSentence, skipFunction, getDeclared, skipAssignment, skipSentenceQueue, createScoped, createString, splice, relink, rolink, pickSentence, snapExpressHead, needBreakBetween } = require("./common");
5
5
  var splice2 = function (q, from, to, ...a) {
6
6
  var cx = q.indexOf(from);
7
7
  if (cx < 0) throw console.log(splice2.caller, console.format(`\r\n<red2>${i18n`自`}</red2>`), from && createString([from]), console.format(`\r\n<yellow>${i18n`至`}</yellow>`), to && createString([to]), console.format(`\r\n<cyan>${i18n`码列`}</cyan>`), createString(pickSentence(from))), i18n`结构异常`;
@@ -1783,28 +1783,34 @@ var down = function (scoped) {
1783
1783
  };
1784
1784
  var precode = function (text) {
1785
1785
  if (!scoped.body) return;
1786
- var codelist = typeof text === 'string' ? scanner2(text) : text;
1787
- var first = codelist[0];
1788
- var last = codelist[codelist.length - 1];
1786
+ var newcode = typeof text === 'string' ? scanner2(text) : text;
1787
+ var first = newcode[0];
1788
+ var last = newcode[newcode.length - 1];
1789
1789
  var top = scoped.first;
1790
1790
  if (top) top.prev = last;
1791
1791
  if (last) last.next = top;
1792
1792
  if (first) delete first.prev;
1793
1793
  scoped.body.first = first || top;
1794
- scoped.body.unshift.apply(scoped.body, codelist);
1794
+ scoped.body.unshift.apply(scoped.body, newcode);
1795
+ mergeTo(scoped.used, newcode.used);
1795
1796
  };
1796
1797
 
1797
1798
  var markcodes = [];
1799
+ var { caps } = scoped;
1798
1800
  if (scoped.isfunc && scoped.caps.this && (funcMark || scoped.insett)) {
1799
1801
  let tn = _getname("this_");
1800
1802
  rename(scoped.caps, "this", tn);
1801
- scoped.caps.this.forEach(o => o.origin = 'this');
1803
+ caps.this.forEach(o => o.origin = 'this');
1804
+ caps[tn] = caps.this;
1805
+ delete caps.this;
1802
1806
  markcodes.push(`${tn}=this`);
1803
1807
  }
1804
1808
  if (scoped.isfunc && scoped.caps.arguments && (funcMark || scoped.inseta)) {
1805
1809
  let an = _getname("arguments_");
1806
- scoped.caps.arguments.forEach(o => o.origin = 'arguments');
1807
- rename(scoped.caps, "arguments", an);
1810
+ caps.arguments.forEach(o => (o.origin = 'arguments', o.type = EXPRESS));
1811
+ rename(caps, "arguments", an);
1812
+ caps[an] = caps.arguments;
1813
+ delete caps.arguments;
1808
1814
  markcodes.push(`${an}=arguments`);
1809
1815
  }
1810
1816
  var fordeep = 0;
@@ -145,7 +145,7 @@
145
145
  var timeNode = document.createTextNode("");
146
146
  var rejectTime = 0;
147
147
  care(this, function ([type, sender, data]) {
148
- if (sender !== remoteUser.id) return;
148
+ if (sender !== remoteUser.cid) return;
149
149
  switch (type) {
150
150
  case "rtc-close":
151
151
  if (acceptTime) return remove(this);
@@ -9,17 +9,17 @@
9
9
  <i></i>
10
10
  <i></i>
11
11
  </btn>
12
- <template -if="user">
13
- <span -bind="user.name"></span>
14
- &nbsp;<span class="id">(<span -bind="user.id"></span>)</span>
15
- <a left -if="user.id!==localid" @click="call()">呼叫</a>
12
+ <template -if="remoteUser">
13
+ <span -bind="remoteUser.name"></span>
14
+ &nbsp;<span class="id">(<span -bind="remoteUser.id"></span>)</span>
15
+ <a left -if="rid!==cid" disabled_="!!remoteUser.shaking" @click="call()">呼叫</a>
16
16
  </template>
17
17
  <template -elseif="title" -src="title"> </template>
18
18
  <close @click="remove()"></close>
19
19
  </div>
20
20
  <list -if="users.length>0" -src="u in users">
21
- <btn class="user" @click="user=u" type_="u===user?'default':'white'">
22
- <avatar -if="user.icon" -style="{'background-image':'url(\'icons/'+u.icon+'.ico\')'}"></avatar>
21
+ <btn class="user" @click="remoteUser=u" type_="u===remoteUser?'default':'white'" -class="{fade:u.shaking}">
22
+ <avatar -if="u.icon" -style="{'background-image':'url(\'icons/'+u.icon+'.ico\')'}"></avatar>
23
23
  <avatar -else>
24
24
  </avatar>
25
25
  <span -text="u.name"></span>&nbsp;
@@ -29,9 +29,17 @@
29
29
  <div>
30
30
  <span class="id" -text="u.id"></span>
31
31
  </div>
32
- <span class="local" -if="u.id===localid">本机</span>
32
+ <span class="local" -if="cid&&u.cid===cid">本机</span>
33
33
  </btn>
34
34
  </list>
35
+
36
+ <div .qrcode -if="rid===cid">
37
+ <canvas @append="qr(this)"></canvas>
38
+ <p>扫码以开启<a target="_blank" href_="linkurl" @click="event.preventDefault();cplink()">公网会话</a></p>
39
+ <p @click="autoAllow=!autoAllow">
40
+ <checker -model="autoAllow"></checker>自动允许会话请求
41
+ </p>
42
+ </div>
35
43
  <grid #body disabled>
36
44
  <chat -src="m in msglist">
37
45
  <padding>
@@ -40,15 +48,16 @@
40
48
  </padding>
41
49
  </chat>
42
50
  <div textarea @mousedown="this.firstChild.focus()">
43
- <div @keydown.alt.enter="send('html',text)" contenteditable="true" -model="text"></div>
51
+ <div @keydown.alt.enter="send('html',text)" contenteditable@="rid!==cid" -model="text"></div>
44
52
  </div>
45
53
  </grid>
46
- <div foot>
47
- <a class="file" @click="chooseFile()" -if="user">
54
+
55
+ <div foot -style="{opacity:rid===cid?0.2:1}">
56
+ <a disabled_="rid===cid||!!remoteUser?.shaking" class="file" @click="chooseFile()" -if="remoteUser">
48
57
  <template -src="fileIcon"></template>
49
58
  <span>
50
59
  ${i18n`文件`}
51
60
  </span>
52
61
  </a>
53
- <a @click="send('html',text);">${i18n`发送`}</a>
62
+ <a disabled_="rid===cid||!!remoteUser?.shaking" @click="send('html',text);">${i18n`发送`}</a>
54
63
  </div>
@@ -11,7 +11,7 @@ function clickfile(event) {
11
11
  }
12
12
 
13
13
  function msg(elem, { m }, parentScopes) {
14
- if (m.sender === parentScopes[parentScopes.length - 1].localid) {
14
+ if (m.sender === parentScopes[parentScopes.length - 1].cid) {
15
15
  elem.setAttribute("self", "");
16
16
  }
17
17
  if (m) switch (m.type) {
@@ -33,20 +33,24 @@ function msg(elem, { m }, parentScopes) {
33
33
  elem.innerText = m.content;
34
34
  }
35
35
  }
36
- var userManager = function (users, map) {
37
- for (var cx = 0, dx = users.length; cx < dx; cx++) {
36
+ var userManager = function (users, map, page) {
37
+ for (var cx = users.length - 1; cx >= 0; cx--) {
38
38
  var u = users[cx];
39
39
  if (u.id in map) {
40
40
  var m = map[u.id];
41
41
  if (m.deleted) users.splice(cx, 1);
42
42
  else Object.assign(u, m);
43
- delete map[u.id];
44
- return;
43
+ if (!u.shake) delete map[u.id];
44
+ else users.splice(cx, 1);
45
45
  }
46
46
  }
47
47
  var ms = Object.keys(map).map(k => map[k]);
48
- for (var u of ms) u.msgread = 0;
49
- users.push.apply(users, ms);
48
+ var us = ms.filter(a => !a.shake);
49
+ for (var u of us) {
50
+ u.msgread = 0;
51
+ }
52
+ users.push.apply(users, us);
53
+ return ms.filter(a => a.shake);
50
54
  };
51
55
  var saved_event, moving = null;
52
56
  var dragpage = {
@@ -113,8 +117,8 @@ var getRtc = function (userid) {
113
117
  return rtc;
114
118
  }
115
119
  async function pullFileWithRTC(scope, file) {
116
- var userid = scope.user.id;
117
- var rtc = getRtc(userid);
120
+ var rid = scope.remoteUser.cid;
121
+ var rtc = getRtc(rid);
118
122
  var h = await window.showSaveFilePicker({ suggestedName: file.name });
119
123
  var writable = await h.createWritable();
120
124
  var channel = await rtc.createChannel();
@@ -156,7 +160,7 @@ async function pullFileWithRTC(scope, file) {
156
160
  // <!-- console.log('接收端异常',event) -->
157
161
  };
158
162
  var ondate = function (date) {
159
- scope.send("didate", date, userid);
163
+ scope.send("didate", date, rid);
160
164
  };
161
165
  var offer = await rtc.init(ondate);
162
166
  scope.send('accept', { file: file.id, channel: channel.id, offer })
@@ -217,6 +221,24 @@ async function pushFileWithRTC(scope, file, msg) {
217
221
  // <!-- console.log("发送端打开") -->
218
222
  };
219
223
  }
224
+ var shakeing = [];
225
+ var shakeUser = async function (page, shakes) {
226
+ if (shakeing.length) return shakeing.push.apply(shakeing, shakes);
227
+ shakeing.push.apply(shakeing, shakes);
228
+ while (shakeing.length) {
229
+ var user = shakeing.shift();
230
+ if (page.autoAllow);
231
+ else {
232
+ var options = [i18n`允许`, i18n`不允许` + '#danger'];
233
+ var res = await confirm(i18n`是否允许来自${user.name}(${user.id})的公网会话?`, options);
234
+ if (res === options[1]) continue;
235
+ }
236
+ delete user.shake;
237
+ page.push([user]);
238
+ await wait(function () { return page.localUser }, 10000);
239
+ page.send(page.localUser, 'user', user.cid);
240
+ }
241
+ }
220
242
 
221
243
 
222
244
  function chat(title = '会话窗口') {
@@ -224,7 +246,6 @@ function chat(title = '会话窗口') {
224
246
  page.innerHTML = template;
225
247
  drag.on(page.firstElementChild, page);
226
248
  resize.on(page);
227
- var localid = title.id || (new Date / 1000 | 0) + Math.sin(Math.random());
228
249
  var users = [];
229
250
  var addToMsgList = function (list, msgs) {
230
251
  list.push.apply(list, msgs);
@@ -234,7 +255,7 @@ function chat(title = '会话窗口') {
234
255
  if (msgs.length && (!lastmsg || lastmsg.offsetTop + lastmsg.offsetHeight === chat.scrollHeight)) {
235
256
  chat.go(list.length ? list.length - 1 : 0);
236
257
  }
237
- if (ps.user) ps.user.msgread = list.length;
258
+ if (ps.remoteUser) ps.remoteUser.msgread = list.length;
238
259
  }
239
260
  else {
240
261
  ps.totalunread += msgs.length;
@@ -243,8 +264,41 @@ function chat(title = '会话窗口') {
243
264
  var msgTemp = Object.create(null);
244
265
  page.push = function (msgs) {
245
266
  var { msglist } = ps;
246
- var userMap = null;
247
267
  var cached = [], cachedi = 0;
268
+ var userMap = null;
269
+ var cidMap = null;
270
+ var addUser = function (m) {
271
+
272
+ if (!userMap) {
273
+ cidMap = Object.create(null);
274
+ users.forEach((u, i) => {
275
+ cidMap[u.cid] = i;
276
+ })
277
+ userMap = Object.create(null);
278
+ }
279
+ if (m.cid in cidMap) {
280
+ var ci = cidMap[m.cid];
281
+ var c = users[ci];
282
+ if (c.shaking) {
283
+ delete userMap[m.id];
284
+ cidMap[m.cid] = m;
285
+ users[ci] = m;
286
+ if (ps.localUser === c) ps.localUser = m;
287
+ if (ps.remoteUser === c) ps.remoteUser = m;
288
+ }
289
+ else if (m.shaking) m = cidMap[m.cid];
290
+ }
291
+ if (!m.icon) {
292
+ if (m.shaking) {
293
+ m.name = "正在开启..";
294
+ m.id = 'loading';
295
+ m.icon = 'chrm';
296
+ }
297
+ else if (m.id) m.icon = m.id.replace(/[\.\d]+$/, '');
298
+ }
299
+ cidMap[m.cid] = m;
300
+ userMap[m.id] = m;
301
+ };
248
302
  msgs = msgs.filter(m => {
249
303
  if (!m) return false;
250
304
  if (isString(m)) {
@@ -271,11 +325,7 @@ function chat(title = '会话窗口') {
271
325
  return true;
272
326
  }
273
327
  switch (m.type) {
274
- case 'user':
275
- if (!userMap) userMap = Object.create(null);
276
- if (!m.icon) m.icon = m.id.replace(/[\.\d]+$/, '');
277
- userMap[m.id] = m;
278
- break;
328
+ case 'user': addUser(m); break;
279
329
  }
280
330
  return false;
281
331
  });
@@ -287,12 +337,20 @@ function chat(title = '会话窗口') {
287
337
  ps.pushFile(m.content);
288
338
  return false;
289
339
  }
340
+ if (m.type === "user") {
341
+ addUser(m);
342
+ return false;
343
+ }
290
344
  return true;
291
345
  });
292
346
  if (userMap) {
293
- userManager(users, userMap);
294
- if (users.indexOf(ps.user) < 0) ps.user = users[0];
347
+ var shakes = userManager(users, userMap, send1);
348
+ shakeUser(page, shakes);
349
+ if (users.indexOf(ps.remoteUser) < 0) ps.remoteUser = users[0];
295
350
  if (users.length > 0 && ps.showList === 0) ps.showList = true;
351
+ for (let u of users) {
352
+ if (u.cid === ps.cid) ps.localUser = u;
353
+ }
296
354
  }
297
355
  if (msgs.length) {
298
356
  var msgMap = Object.create(null);
@@ -328,9 +386,9 @@ function chat(title = '会话窗口') {
328
386
  }
329
387
  }
330
388
  if (users.length) for (var u of users) {
331
- if (u.id in msgMap) {
389
+ if (u.cid in msgMap) {
332
390
  if (!u.msglist) u.msglist = [];
333
- addToMsgList(u.msglist, msgMap[u.id]);
391
+ addToMsgList(u.msglist, msgMap[u.cid]);
334
392
  }
335
393
  }
336
394
  else {
@@ -341,13 +399,14 @@ function chat(title = '会话窗口') {
341
399
  page.$renders = [function () {
342
400
  ps.resize(ps.body);
343
401
  }];
344
- page.localid = localid;
345
- Object.defineProperty(page, 'userid', {
402
+
403
+ Object.defineProperty(page, 'rid', {
346
404
  get() {
347
- var user = ps.user;
348
- if (user) return user.id;
405
+ var user = ps.remoteUser;
406
+ if (user) return user.cid;
349
407
  }
350
408
  });
409
+
351
410
  page.setAttribute('ng-class', "{showList:showList}");
352
411
  var fid = 0;
353
412
  var filesMap = Object.create(null);
@@ -357,19 +416,20 @@ function chat(title = '会话窗口') {
357
416
  ps.send('rtc-video', data);
358
417
  break;
359
418
  case "hangup":
360
- ps.send('rtc-close', "", ps.remote);
419
+ ps.send('rtc-close', "", ps.remoteRtc);
361
420
  break;
362
421
  case "accept":
363
- ps.send('rtc-accept', data, ps.remote);
422
+ ps.send('rtc-accept', data, ps.remoteRtc);
364
423
  break;
365
424
  case "didate":
366
- ps.send('rtc-didate', data, ps.remote);
425
+ ps.send('rtc-didate', data, ps.remoteRtc);
367
426
  break;
368
427
  }
369
428
  }
370
429
  function send1(msg, sendto) {
371
430
  cast(page, 'send', [sendto, msg]);
372
431
  }
432
+ page.autoAllow = true;
373
433
  var ps = {
374
434
  chat: zimoli$list,
375
435
  title,
@@ -377,45 +437,92 @@ function chat(title = '会话窗口') {
377
437
  showList: 0,
378
438
  users,
379
439
  text: '',
440
+ get autoAllow() {
441
+ return page.autoAllow;
442
+ },
443
+ set autoAllow(v) {
444
+ return page.autoAllow = v;
445
+ },
380
446
  calling: null,
381
- remote: null,
382
- localid,
447
+ remoteRtc: null,
448
+ get localUser() {
449
+ return page.localUser
450
+ },
451
+ set localUser(v) {
452
+ page.localUser = v;
453
+ },
454
+ get shaking() {
455
+ var u = this.remoteUser;
456
+ if (u) return u.shaking;
457
+ },
458
+ get localid() {
459
+ return page.clientid;
460
+ },
461
+ set localid(v) {
462
+ page.clientid = v;
463
+ },
464
+ get cid() {
465
+ return this.localid;
466
+ },
467
+ get rid() {
468
+ if (this.remoteUser) return this.remoteUser.cid;
469
+ },
470
+ text: '',
383
471
  totalunread: 0,
384
- _user: null,
385
- call(remote = this.user, offer) {
472
+ get linkurl() {
473
+ var href = location.href.replace(/[?#][\s\S]*$/, '') + "?" + this.cid;
474
+ return href;
475
+ },
476
+ async qr(canvas) {
477
+ var qrcode = await init("thirdParty$qrcode");
478
+ var qr = qrcode(0, 'L');
479
+ var href = this.linkurl;
480
+ qr.addData(href);
481
+ qr.make();
482
+ var size = qr.getModuleCount();
483
+ canvas.width = canvas.height = size;
484
+ while (size < 128) size = size << 1;
485
+ css(canvas, { width: size, height: size });
486
+ qr.renderTo2dContext(canvas.getContext("2d"), 1);
487
+ },
488
+ cplink() {
489
+ copyToClipboard(this.linkurl);
490
+ },
491
+ call(remote = this.rid, offer) {
386
492
  if (this.calling) return;
387
- this.remote = isObject(remote) ? remote.id : remote;
493
+ this.remoteRtc = isObject(remote) ? remote.cid : remote;
494
+ console.log(remote)
388
495
  if (typeof remote === 'string') {
389
496
  for (var u of this.users) {
390
- if (u.id === remote) {
497
+ if (u.cid === remote) {
391
498
  remote = u;
392
499
  break;
393
500
  }
394
501
  }
395
502
  }
396
503
  if (!remote) return;
397
- var c = chatRtc(remote, this.localid, offer);
504
+ var c = chatRtc(remote, this.cid, offer);
398
505
  this.calling = c;
399
506
 
400
507
  on('remove')(c, function () {
401
508
  ps.calling = null;
402
- ps.remote = null;
509
+ ps.remoteRtc = null;
403
510
  })
404
511
  care(c, rtcMessage);
405
512
  popup(c);
406
513
  },
407
514
  fileIcon: shapes$file,
408
- set user(v) {
515
+ set remoteUser(v) {
409
516
  if (!v.msglist) v.msglist = []
410
517
  if (v.msgread !== v.msglist.length) {
411
518
  v.msgread = v.msglist.length;
412
519
  this.totalunread -= v.msglist.length - v.msgread;
413
520
  }
414
521
  this.msglist = v.msglist;
415
- this._user = v;
522
+ page.remoteUser = v;
416
523
  },
417
- get user() {
418
- return this._user;
524
+ get remoteUser() {
525
+ return page.remoteUser;
419
526
  },
420
527
  msg,
421
528
  remove() {
@@ -470,10 +577,15 @@ function chat(title = '会话窗口') {
470
577
  body.resizeCell(textarea, 'top', textarea.clientHeight - targetHeight - 2);
471
578
  },
472
579
 
473
- send(type, content, sendto = page.userid) {
474
- var msg = {
580
+ send(type, content, sendto = page.rid) {
581
+ console.log(type, content, 'send', sendto, this.text)
582
+ if (type instanceof Object) {
583
+ var msg = type;
584
+ if (!msg.type) msg.type = content;
585
+ }
586
+ else var msg = {
475
587
  type,
476
- sender: this.localid,
588
+ sender: this.localUser.cid,
477
589
  content,
478
590
  };
479
591
  var data = JSAM.stringify(msg);
@@ -481,7 +593,7 @@ function chat(title = '会话窗口') {
481
593
  if (data.length > 16000) {
482
594
  return alert("信息太长,无法发送!");
483
595
  }
484
- if (this.user && this.user.id !== this.localid) a: {
596
+ if (this.remoteUser && this.remoteUser.cid !== this.cid) a: {
485
597
  switch (type) {
486
598
  case "accept":
487
599
  case "didate":
@@ -505,7 +617,7 @@ function chat(title = '会话窗口') {
505
617
  else {
506
618
  send1(data, sendto);
507
619
  }
508
- this.body.lastElementChild.focus();
620
+ if (this.body) this.body.lastElementChild.focus();
509
621
  this.text = '';
510
622
  }
511
623
  };
@@ -520,5 +632,6 @@ function chat(title = '会话窗口') {
520
632
  }
521
633
  });
522
634
  moveupon(page, dragpage);
635
+ page.send = ps.send.bind(ps);
523
636
  return page;
524
637
  }