diff --git a/const.js b/const.js index f53b40fd..a2da6a8e 100644 --- a/const.js +++ b/const.js @@ -414,7 +414,7 @@ var icon = { portal: "bi bi-globe", desktop: "bi bi-window-desktop", admin: "bi bi-window-sidebar", dream: "bi bi-box", space: "bi bi-box", store: "bi bi-shop", - word: "bi bi-book", repos: "bi bi-git", vimer: "bi bi-bug", build: "bi bi-tools", xterm: "bi bi-terminal", + word: "bi bi-book", repos: "bi bi-git", vimer: "bi bi-bug", build: "bi bi-tools", xterm: "bi bi-terminal", shell: "bi bi-terminal", stats: "bi bi-card-list", matrix: "bi bi-grid-3x3-gap", feel: "bi bi-images", diff --git a/frame.js b/frame.js index 9edaef4e..102cfa60 100644 --- a/frame.js +++ b/frame.js @@ -740,10 +740,20 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { ui.display && can.onmotion.hidden(can, ui.display), ui.profile && can.onmotion.hidden(can, ui.profile) ui.layout = function(height, width, delay, cb) { can.onmotion.delay(can, function() { defer = [], layout(type, ui.list, height, width), defer.forEach(function(cb) { cb() }) - if (can.db.value) { can.db.value._display_plugin && (height = height/2-1), can.page.style(can, can.ui.content, html.HEIGHT, height) - can.db.value._content_plugin && can.db.value._content_plugin.onimport.size(can.db.value._content_plugin, height, content_width, false) - can.db.value._display_plugin && can.db.value._display_plugin.onimport.size(can.db.value._display_plugin, height, content_width, false) + if (can.db.value) { var _width = can.ConfWidth(); width = width-can.ui.project.offsetWidth + if (can.isCmdMode()) { + can.page.SelectChild(can, can._fields, "legend,form.option,div.header", function(target) { _width -= target.offsetWidth }) + can.page.SelectChild(can, can._fields, "div.action", function(target) { can.page.style(can, target, html.MAX_WIDTH, _width-1) + can.page.Select(can, target, "span.name", function(target, index, list) { can.page.style(can, target, html.MAX_WIDTH, (_width-50)/list.length-40) }) + }) + } + can.db.value._display_plugin && (height = height/2), can.page.style(can, can.ui.content, html.HEIGHT, height) + can.db.value._display_plugin && can.db.value._display_plugin.onimport.size(can.db.value._display_plugin, height-1, width, false) can.db.value._display_plugin && can.onmotion.toggle(can, can.ui.display, true) + can.db.value._profile_plugin && (width = width/2), can.page.style(can, can.ui.content, html.WIDTH, width) + can.db.value._profile_plugin && can.db.value._profile_plugin.onimport.size(can.db.value._profile_plugin, height, width-1, false) + can.db.value._profile_plugin && can.onmotion.toggle(can, can.ui.profile, true) + can.db.value._content_plugin && can.db.value._content_plugin.onimport.size(can.db.value._content_plugin, height, width, false) } cb && cb(content_height, content_width) }, delay||0) } can.onimport.layout = can.onimport.layout||function(can) { diff --git a/index.css b/index.css index f0065a1e..d97be8ec 100644 --- a/index.css +++ b/index.css @@ -189,6 +189,13 @@ div.output>div.code>div.form { text-align:center; font-size:15px; padding:60px 1 div.output>div.code>div.form>input[type=button] { min-width:200px; } div.output>div.code>div.form>input[type=button][name=confirm] { background-color:var(--notice-bg-color); color:var(--notice-fg-color); margin:var(--button-margin) 0; } body.en span[lang^=zh] { display:none; } body.zh span[lang^=en] { display:none; } + +// fieldset.plugin.cmd { display:flex; flex-wrap:wrap; justify-content:space-between; } +fieldset.plugin.cmd:not(.output)>form.option { float:left; display:flex !important; } +fieldset.plugin.cmd:not(.output)>div.action { float:left; display:flex !important; flex-grow:1; height:var(--action-height); overflow:auto; } +fieldset.plugin.cmd:not(.output)>div.action div.tabs.select { padding-top:2px; } +fieldset.plugin.cmd:not(.output)>div.action div.tabs>span.name { overflow:hidden; } +fieldset.plugin.cmd:not(.output)>div.header { float:right; display:flex !important; flex-direction:row-reverse; } /* project */ div.project div.action:not(.hide) { width:100%; display:flex; } div.project div.action div.item input { border-right:var(--box-border); } @@ -535,6 +542,8 @@ div.float { box-shadow:var(--plugin-box-shadow); border:var(--plugin-border); } div.float:hover { box-shadow:var(--notice-box-shadow); } fieldset.plugin { box-shadow:var(--plugin-box-shadow); border-radius:var(--plugin-radius); } fieldset.story { box-shadow:var(--plugin-box-shadow); border-radius:var(--plugin-radius); } +fieldset.studio fieldset.story { border-radius:0; } +fieldset.studio fieldset.story>legend { border-top-left-radius:0; } fieldset.float { box-shadow:var(--plugin-box-shadow); border:var(--plugin-border); border-radius:var(--plugin-radius); } fieldset:not(.panel):hover { box-shadow:var(--notice-box-shadow); } body:not(.cmd) fieldset.plugin>legend { box-shadow:var(--legend-box-shadow); margin-right:var(--legend-margin); } @@ -966,6 +975,7 @@ div.project::-webkit-scrollbar { width:0 !important; height:0 !important; } div.project div.list::-webkit-scrollbar { width:0 !important; height:0 !important; } div.content::-webkit-scrollbar { width:0 !important; height:0 !important; } div.status::-webkit-scrollbar { width:0 !important; height:0 !important; } +div.action::-webkit-scrollbar { width:0 !important; height:0 !important; } div.toggle::-webkit-scrollbar { width:0 !important; height:0 !important; } div.story[data-type=spark]::-webkit-scrollbar { width:0 !important; height:0 !important; } div.toast.float div.title::-webkit-scrollbar { width:0 !important; height:0 !important; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 5f1c7025..188973f6 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -23,6 +23,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp } can.db = {paths: paths, tabview: {}, history: [], _history: [], toolkit: {}}, can.db.tabview[can.onexport.keys(can)] = msg can.ui = can.onappend.layout(can, [html.PROJECT, [html.TABS, nfs.PATH, [html.CONTENT, html.PROFILE], html.DISPLAY, html.PLUG]]) + can.onmotion.toggle(can, can.ui.tabs, true) can.ui._content = can.ui.content, can.ui._profile = can.ui.profile, can.ui._display = can.ui.display, can.onmotion.hidden(can, can.ui.plug) can.onmotion.hidden(can, can.ui.profile), can.onmotion.hidden(can, can.ui.display) if (can.Conf(ctx.STYLE) == html.OUTPUT) { can.onmotion.hidden(can, can.ui.project), can.page.style(can, can.ui.content, html.HEIGHT, "") } diff --git a/plugin/state.js b/plugin/state.js index 806dd686..5db4bbff 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -18,7 +18,7 @@ Volcanos(chat.ONIMPORT, { _field: function(can, msg, cb) { var height = can.ConfHeight()-can.onexport.actionHeight(can)-(can.onexport.statusHeight(can)||1), width = can.ConfWidth() var tabs = false, tabHash = msg.Option("field.tabs"); if (tabHash) { - can.sub && can.sub.onimport.tabs(can, [{name: tabHash.slice(0, 6)}], function() { can.onmotion.cache(can, function() { return tabHash }) }), tabs = true + can.sub && can.sub.onimport.tabs(can.sub, [{name: tabHash.slice(0, 6)}], function() { can.onmotion.cache(can, function() { return tabHash }) }), tabs = true } else { if (msg.Length() > 1) { height = height / msg.Length() @@ -32,7 +32,7 @@ Volcanos(chat.ONIMPORT, { can.page.ClassList.has(can, sub._target, html.FLOAT)? can.onmotion.float(sub): sub.onimport.size(sub, height, width, true), cb && cb(sub) if (item.style == html.FLOAT) { return } can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, sub._target) }, 300) sub.onexport.output = function() { if (tabs) { msg.Option(ice.MSG_ACTION) && can.onappend._action(can, msg.Option(ice.MSG_ACTION)) - sub.sub.onimport.tabs(can, [{name: tabHash.slice(0, 6)}], function() { tabs || can.onmotion.cache(can, function() { return tabHash }) }), tabs = false + sub.sub.onimport.tabs(sub.sub, [{name: tabHash.slice(0, 6)}], function() { tabs || can.onmotion.cache(can, function() { return tabHash }) }), tabs = false } } }, item.style == html.FLOAT && can.page.tagis(can._target, "fieldset.story")? document.body: can._output) }) diff --git a/plugin/story/studiolayout.css b/plugin/story/studiolayout.css index 1d980d9b..15e92190 100644 --- a/plugin/story/studiolayout.css +++ b/plugin/story/studiolayout.css @@ -1,5 +1,5 @@ -fieldset.studiolayout>div.output>div.project div.item { border-left:var(--box-border3); } -fieldset.studiolayout>div.output>div.project div.item.select { border-left:var(--box-notice3); } +// fieldset.studiolayout>div.output>div.project div.item { border-left:var(--box-border3); } +// fieldset.studiolayout>div.output>div.project div.item.select { border-left:var(--box-notice3); } fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.delete { display:none; } fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.sess { display:none; } fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>div.action>div.item.state { display:none; } diff --git a/plugin/story/studiolayout.js b/plugin/story/studiolayout.js index 63c5fc02..3c2d6e83 100644 --- a/plugin/story/studiolayout.js +++ b/plugin/story/studiolayout.js @@ -6,46 +6,14 @@ Volcanos(chat.ONIMPORT, { content: {index: "web.code.redis.keys", args: sess}, } }) }, - _nick: function(can, value) { return value.name }, project: function(can, msg, key, cb) { can.ui = can.onappend.layout(can), can.onappend.style(can, "studiolayout", can._fields) - var last = can.db.hash[0]||can.misc.localStorage(can, can.core.Keys(can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), html.PROJECT)) - var _select; msg.Table(function(value) { var hash = value[key]; value.nick = can.onimport._nick(can, value) - var target = can.onimport.item(can, value, function(event, value) { can.onexport.hash(can, hash) - if (can.onmotion.cache(can, function(save, load) { - save({ - _content: can.ui._content_plugin, _profile: can.ui._profile_plugin, _display: can.ui._display_plugin, - }), load(hash, function(bak) { - can.ui._content_plugin = bak._content, can.ui._profile_plugin = bak._profile, can.ui._display_plugin = bak._display - }) - return hash - }, can.ui.content, can.ui.profile, can.ui.display)) { - can.onmotion.select(can, can._action, html.DIV_TABS, value._tabs); return - } - // can.isStoryType() && (value.nick = value.nick.slice(0, 6)) - value.nick = value.nick.slice(0, 6) - value._tabs = can.onimport.tabs(can, [value], function() { target.click() }, function() { - delete(can.ui.content._cache[hash]), delete(can.ui.profile._cache[hash]), delete(can.ui.display._cache[hash]) - delete(can._cache_data[hash]), delete(value._tabs) - }) - can.core.Item(cb(event, hash, value), function(key, item) { if (!item) { return } - can.onmotion.toggle(can, can.ui[key], true) - can.onappend.plugin(can, item, function(sub) { can.ui["_"+key+"_plugin"] = sub - can.onimport.layout(can), sub.onexport.output = function() { can.onimport.layout(can) } - }, can.ui[key]) - }) - }); _select = _select||target, value.sess == last && (_select = target) - }), _select && _select.click() + msg.Table(function(value) { var hash = value[key]; value._select = can.db.hash[0] == hash + can.onimport.item(can, value, function(event, value, show, target) { if (value._tabs) { return value._tabs.click() } + var msg = can.request(event), list = cb(event, hash, value) + can.core.List("content,display,profile".split(","), function(field) { + list[field] && can.core.List("index,args,style,_init".split(","), function(key) { msg.Push(key, list[field][key]||"") }) + }), can.onimport.tabsCache(can, msg, hash, value, target) + }) + }) }, - layout: function(can) { can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) { - var height = can.ConfHeight(), width = (can.ConfWidth()-can.ui.project.offsetWidth), margin = 0 - can.ui._profile_plugin && (width /= 2), can.ui._display_plugin && (height /= 2) - can.ui._content_plugin && can.ui._content_plugin.onimport.size(can.ui._content_plugin, height-margin, width-margin-1, false) - can.ui._profile_plugin && can.ui._profile_plugin.onimport.size(can.ui._profile_plugin, height-margin, width-margin-1, false) - can.ui._display_plugin && can.ui._display_plugin.onimport.size(can.ui._display_plugin, height-margin-2, width*2-margin, false) - }) }, }, [""]) -Volcanos(chat.ONEXPORT, { - hash: function(can, hash) { can.misc.SearchHash(can, hash) - can.misc.localStorage(can, can.core.Keys(can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), html.PROJECT), hash) - }, -}) diff --git a/plugin/table.js b/plugin/table.js index 7115ca10..ac01f226 100644 --- a/plugin/table.js +++ b/plugin/table.js @@ -102,7 +102,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { return icon && (can.base.contains(icon, ice.HTTP, ".ico", ".png", ".jpg")? {img: can.misc.Resource(can, icon)}: {icon: icon}) }, _nick: function(can, item) { - return {text: item.nick||item.name||item.zone||item.sess} + return {text: [item.nick||item.name||item.zone||item.sess, "", html.NAME], className: html.NAME} }, _menu: function(event, can, item, cbs, target) { target = target||event.currentTarget if (can.base.isFunc(cbs)) { var menu = cbs(event, target, item); if (menu) { return can.user.carteRight(event, can, menu.meta, menu.list, menu) } } @@ -122,7 +122,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { }, item: function(can, item, cb, cbs, _target) { return can.page.Append(can, _target||can.ui.project||can._output, [can.onimport._item(can, item, function(event) { var target = event.currentTarget - can.onmotion.select(can, _target, html.DIV_ITEM, target) + can.onmotion.select(can, target.parentNode, html.DIV_ITEM, target) var show = target._list && can.onmotion.toggle(can, target._list); cb(event, item, show, target) }, cbs)])._target }, @@ -162,7 +162,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { node[name] = ui.list, (item._select || can.db.hash && (can.db.hash[0]||"").indexOf(key) == 0) && can.onmotion.delayOnce(can, function() { ui.item.click() }) }) }); return node }, - tabs: function(can, list, cb, cbs, action) { action = action||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) { if (typeof tabs == code.STRING) { tabs = {name: tabs} } + tabs: function(can, list, cb, cbs, action) { action = action||can.ui.tabs||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) { if (typeof tabs == code.STRING) { tabs = {name: tabs} } function close(target) { if (can.page.ClassList.has(can, target, html.SELECT)) { var next = can.page.tagis(target.nextSibling, html.DIV_TABS)? target.nextSibling: can.page.tagis(target.previousSibling, html.DIV_TABS)? target.previousSibling: null @@ -171,10 +171,11 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { } return {view: [[html.TABS, tabs.type, tabs.role, tabs.status]], title: tabs.title||tabs.text, list: [ can.onimport._icons(can, tabs), can.onimport._nick(can, tabs), {icon: mdb.DELETE, onclick: function(event) { tabs._target._close(), can.onkeymap.prevent(event) }}, - ], onclick: function(event) { if (can.page.ClassList.has(can, tabs._target, html.SELECT)) { return } + ], onclick: function(event) { + event.currentTarget.scrollIntoView() + if (can.page.ClassList.has(can, tabs._target, html.SELECT)) { return } can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs) - }, oncontextmenu: function(event) { - var target = tabs._target, _action = can.page.parseAction(can, tabs) + }, oncontextmenu: function(event) { var target = tabs._target, _action = can.page.parseAction(can, tabs) var menu = tabs._menu||shy(function(event, button) { can.Update(event, [ctx.ACTION, button]) }) can.user.carte(event, can, kit.Dict( "Close", function(event) { target._close() }, @@ -203,6 +204,10 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { if (msg.Append(ctx.INDEX)) { msg.Table(function(value, index) { index == 0 && can.onappend.plugin(can, value, function(sub) { can.db.value._content_plugin = sub, can.onimport.layout(can) }, can.ui.content) index == 1 && can.onappend.plugin(can, value, function(sub) { can.db.value._display_plugin = sub, can.onimport.layout(can) }, can.ui.display) + index == 2 && can.onappend.plugin(can, value, function(sub) { can.db.value._profile_plugin = sub, can.onimport.layout(can) }, can.ui.profile) + can.onmotion.delay(can, function() { can.onimport.layout(can) }) + can.onmotion.delay(can, function() { can.onimport.layout(can) }, 100) + can.onmotion.delay(can, function() { can.onimport.layout(can) }, 300) }) } else { can.onappend.table(can, msg), can.onappend.board(can, msg) } }, function() { delete(value._tabs), can.onmotion.cacheClear(can, key, can.ui.content, can.ui.profile, can.ui.display) }) },