From b6dc209117ae0b28b2e1773782d395967604839d Mon Sep 17 00:00:00 2001 From: shy Date: Tue, 5 Dec 2023 04:04:27 +0800 Subject: [PATCH] opt grow --- frame.js | 2 ++ lib/page.js | 6 ++++-- panel/header.js | 7 ++++--- plugin/input/key.js | 6 +++--- plugin/local/code/xterm.js | 11 +++++++---- plugin/local/team/plan.css | 2 +- plugin/state.js | 20 ++++++++++++++++++-- 7 files changed, 39 insertions(+), 15 deletions(-) diff --git a/frame.js b/frame.js index 6a458602..248abfc6 100644 --- a/frame.js +++ b/frame.js @@ -354,6 +354,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }, table: function(can, msg, cb, target, keys) { if (!msg || msg.Length() == 0) { return } var meta = can.base.Obj(msg.Option(mdb.META)) if (can.user.isMobile) { can.base.toLast(msg.append, mdb.TIME) } can.base.toLast(msg.append, web.LINK), can.base.toLast(msg.append, ctx.ACTION) + if (msg.append[msg.append.length-1] == ctx.ACTION && (!msg[ctx.ACTION] || msg[ctx.ACTION].length == 0)) { msg.append.pop() } var table = can.page.AppendTable(can, msg, target||can._output, msg.append, cb||function(value, key, index, data, list) { if (msg.append.length == 2 && msg.append[0] == mdb.KEY && msg.append[1] == mdb.VALUE) { if (key == mdb.VALUE) { key = data.key } data = {}, can.core.List(list, function(item) { data[item.key] = item.value }) } function run(event, cmd, arg) { can.misc.Event(event, can, function(msg) { can.run(can.request(event, data, can.Option()), [ctx.ACTION, cmd].concat(arg)) }) } @@ -383,6 +384,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }) }, title: can.user.trans(can, can.Option(key) == undefined? key: "click to detail", null, html.INPUT), _init: function(target) { key == ctx.ACTION && can.onappend.mores(can, target, data, can.user.isMobile? can.user.isLandscape() || msg.IsDetail()? 5: 3: can.isCmdMode() || msg.IsDetail()? 10: 5) + can.page.SelectOne(can, target, html.SPAN, function(span) { can.core.List(span.style, function(key) { target.style[key] = span.style[key] }) }) can.page.style(can, target, "cursor", can.base.isIn(key, mdb.KEY, mdb.TIME)? "default": can.Option(key) != undefined? "pointer": "text") }} }); table && can.onappend.style(can, chat.CONTENT, table), table && msg.IsDetail() && can.onappend.style(can, mdb.DETAIL, table) diff --git a/lib/page.js b/lib/page.js index 14506186..7ae46edb 100644 --- a/lib/page.js +++ b/lib/page.js @@ -70,9 +70,11 @@ Volcanos("page", { data.onkeydown = function(event) { can.base.isFunc(list[1]) && list[1](event) } data.onkeyup = function(event) { can.base.isFunc(list[2]) && list[2](event) } } else if (item.username) { var list = can.core.List(item.username); type = html.INPUT, name = list[0]||name||html.USERNAME - data.className = list[1]||data.className||name, data.autocomplete = data.autocomplete||html.USERNAME + // data.className = list[1]||data.className||name, data.autocomplete = data.autocomplete||html.USERNAME + data.className = list[1]||data.className||name } else if (item.password) { var list = can.core.List(item.password); type = html.INPUT, name = list[0]||name||html.PASSWORD - data.className = list[1]||data.className||name, data.type = html.PASSWORD, data.autocomplete = data.autocomplete||"current-password" + // data.className = list[1]||data.className||name, data.type = html.PASSWORD, data.autocomplete = data.autocomplete||"current-password" + data.className = list[1]||data.className||name, data.type = html.PASSWORD } else if (item.img) { var list = can.core.List(item.img); type = html.IMG, data.src = list[0] } else if (item.row) { type = html.TR, item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} }) } else if (item.th) { type = html.TR, item.list = item.th.map(function(text) { return {text: [text, html.TH]} }) diff --git a/panel/header.js b/panel/header.js index befd0ccc..79ec6404 100644 --- a/panel/header.js +++ b/panel/header.js @@ -12,13 +12,13 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.core.CallFunc([can.onaction, item], [event, can, item]) }, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) item == aaa.AVATAR && can.page.Append(can, target, [{img: lex.SP}]) - item == aaa.LANGUAGE && can.page.Append(can, target, [{text: "en / 中"}]) + item == aaa.LANGUAGE && can.page.Append(can, target, [{text: "EN"}, {text: " / "}, {text: "中"}]) item == chat.THEME && can.page.Append(can, target, [{icon: icon.SUN}, {text: " / "}, {icon: icon.MOON}]) }}]) }) }, _language: function(can) { can.page.Select(can, can._output, "div.item.language", function(target) { can.page.Appends(can, target, can.user.info.language.indexOf("zh") == 0? - [{text: "中"}, {text: " / "}, {text: "en"}]: [{text: "en"}, {text: " / "}, {text: "中"}] + [{text: "中"}, {text: " / "}, {text: "EN"}]: [{text: "EN"}, {text: " / "}, {text: "中"}] ) }) }, _theme: function(can, theme) { return can.ui.diy&&can.ui.diy[theme]||theme }, @@ -74,8 +74,9 @@ Volcanos(chat.ONACTION, {_init: function(can) {}, onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, onmain: function(can) { if (!can.user.isMailMaster) { if (can.misc.Search(can, ice.MSG_SESSID)) { can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID)); return can.misc.Search(can, ice.MSG_SESSID, "") } } - function lang(msg, cb) { can.user.info.language = msg.SearchOrOption(aaa.LANGUAGE), can.onmotion.delay(can, function() { can.onimport._language(can) }) + function lang(msg, cb) { can.user.info.language = msg.SearchOrOption(aaa.LANGUAGE) can.user.info.language? can.require([can.misc.Resource(can, nfs.SRC_TEMPLATE+web.CHAT_HEADER+"/language/"+can.user.info.language+".js")], cb, function(can, name, sub) { can.base.Copy(can.user._trans, sub._trans) }): cb && cb() + can.onmotion.delay(can, function() { can.onimport._language(can) }) } function show(msg) { var p = can.misc.Search(can, "redirect_uri") if (p && location.pathname == web.BASIC_LOGIN) { return location.replace(can.base.MergeURL(p, ice.MSG_SESSID, can.misc.CookieSessid(can))) } diff --git a/plugin/input/key.js b/plugin/input/key.js index ebfb84d1..e575b777 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -21,9 +21,9 @@ Volcanos(chat.ONFIGURE, {key: { msg.append.length == 1 && can.page.ClassList.add(can, can._target, chat.SIMPLE), can.onlayout.figure({target: target}, can, can._target, false, 200) can.onmotion.toggle(can, can._target, can.Status("total") > 0) }, - onclick: function(event, can, meta, target, cbs) { - // can.onmotion.focus(can, target) - }, + onclick: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return } + meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value) + }) }, onfocus: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return } meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value) }) }, diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index a2ea5f50..4b050342 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -1,9 +1,10 @@ (function() { const RECOVER_STORE = "recover:" Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules(can, ["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() { - var item = msg.TableDetail(); item.hash = item.hash||can.Option(mdb.HASH), can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg), can.onappend._status(can), can.onkeymap._build(can) + var item = can.base.Obj(msg.TableDetail(), {hash: "only"}); item.hash = item.hash||can.Option(mdb.HASH), can.onmotion.clear(can) if (item.type == html.LAYOUT) { can.onimport._layout(can, item) } else { can.onimport._connect(can, item, can._output) } can.onimport.layout(can) can.sup.onexport.link = function() { return can.misc.MergePodCmd(can, {pod: can.Conf(ice.POD), cmd: web.CODE_XTERM, hash: item.hash}) } can.sup.onexport.title(can, item.name||item.type) + can.base.isFunc(cb) && cb(msg), can.onappend._status(can), can.onkeymap._build(can) }) }, _layout: function(can, item) { function connect(item, output, tabs) { can.run(can.request({}, item), [item.hash], function(msg) { @@ -55,7 +56,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules can.page.Select(can, can._fields, html.DIV_OUTPUT, function(target) { can.page.ClassList.set(can, target, html.SELECT, target == output) }) }; return can.db = can.db||{}, can.db[item.hash] = term }, - _recover: function(can, item, term, text) { var recover = can.onexport.session(can, RECOVER_STORE+item.hash) + _recover: function(can, item, term, text) { + // var recover = can.onexport.session(can, RECOVER_STORE+item.hash) + var recover = "" if (recover) { can.onexport.session(can, RECOVER_STORE+item.hash, ""), can.onmotion.delay(can, function() { term.write(recover.replaceAll(lex.NL, "\r\n")) }) } can.onengine.listen(can, chat.ONUNLOAD, function(msg) { term.selectAll(), can.onexport.session(can, RECOVER_STORE+item.hash, can.base.trimSuffix(term.getSelection(), lex.NL)+lex.NL) }) text && can.onmotion.delay(can, function() { term.write(text.replaceAll(lex.NL, "\r\n")) }) @@ -82,8 +85,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules }), can._output = term._output } }, - grow: function(can, msg) { - var arg = msg.detail.slice(1), term = can.db[arg[0]]; arg[1] == "~~~end~~~"? can.onaction.delete(can, term._output): term.write(arg[1]); msg.Option(ice.LOG_DISABLE, ice.TRUE) + grow: function(can, msg, hash, text) { var arg = msg.detail.slice(1); arg = [hash||arg[0], text||arg[1]] + term = can.db[arg[0]]; arg[1] == "~~~end~~~"? can.onaction.delete(can, term._output): term.write(arg[1]); msg.Option(ice.LOG_DISABLE, ice.TRUE) }, layout: function(can) { function show(target, height, width) { var list = can.page.SelectChild(can, target, can.page.Keys(html.DIV_OUTPUT, html.DIV_LAYOUT)) var h = height/list.length, w = width; if (can.page.ClassList.has(can, target, html.FLEX)) { h = height, w = width/list.length } if (target == can._fields) { h = height, w = width } diff --git a/plugin/local/team/plan.css b/plugin/local/team/plan.css index 6c8f1760..7223c473 100644 --- a/plugin/local/team/plan.css +++ b/plugin/local/team/plan.css @@ -12,7 +12,7 @@ fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div. fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.prepare { background-color:#0000ff70; } fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.process { background-color:#00800070; } fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.cancel { background-color:#ff000070; text-decoration:line-through; } -fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.finish { background-color:gray; } +fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.finish { background-color:#8080809c; } fieldset.plan>div.output>div.layout>div.layout>div.content>table.content tr:first-child { height:30px; position:sticky; top:2px; } fieldset.plan>div.output>div.layout>div.layout>div.content>table.content th:first-child { width:40px; position:sticky; left:2px; } fieldset.plan>div.output>div.layout>div.layout>div.profile>table.content tr:first-child { height:30px; position:sticky; top:2px; } diff --git a/plugin/state.js b/plugin/state.js index f9135f13..45a7be52 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -30,8 +30,24 @@ Volcanos(chat.ONIMPORT, { var head = can.page.Select(can, can._output, [html.TABLE_CONTENT, html.TH], function(th) { return th.innerText }) return can.page.Append(can, table, msg.Table(function(value) { return {row: can.core.List(head, function(key) { return value[key] })} })) }).length == 0) { can.onappend.table(can, msg) } }, - _grow: function(can, msg, arg) { var sub = can.sub - if (sub && sub.onimport && sub.onimport.grow) { return sub.onimport.grow(sub, msg, arg) } + _grow: function(can, msg, arg) { + var sub = can.sub; if (sub && sub.onimport && sub.onimport.grow) { return sub.onimport.grow(sub, msg, msg.detail[1], msg.detail[2]) } + if (msg.Option(ctx.DISPLAY)) { + function _grow() { if (can.sub._grow_list.length == 0) { return } if (can.sub._grow_running) { return } can.sub._grow_running = true + var msg = can.sub._grow_list.shift(), list = [], text = msg.detail[1]; for (var i = 0; i < text.length; i++) { list.push(text[i]) } + can.core.Next(list, function(text, next) { can.core.Timer(30, next), can.sub._grow.onimport.grow(can.sub._grow, msg, "only", text) }, function() { can.sub._grow_running = false, _grow() }) + } + if (can.sub._grow) { + (can.sub._grow_list = can.sub._grow_list||[]).push(msg); return _grow() + } else { + (can.sub._grow_list = can.sub._grow_list||[]).push(msg); if (can.sub._grow_list.length > 1) { return } + } + var height = can.onexport.outputHeight(can) + can.onappend.plugin(can, {index: "can._plugin", title: msg.Option(ctx.DISPLAY).split(nfs.PS).pop(), display: msg.Option(ctx.DISPLAY), height: height}, function(sub) { + sub.onexport.output = function() { can.sub._grow = sub.sub, _grow() } + }) + return + } arg = can.page.Color(arg); if (!can.page.SelectOne(can, can._output, html.DIV_CODE, function(div) { return can.page.style(can, div, html.MAX_HEIGHT, can.onexport.outputHeight(can)), can.page.Append(can, div, [{text: arg}]), can._output.scrollTop = div.offsetTop, div.scrollBy(0, 10000), true