diff --git a/frame.js b/frame.js index eb40e7d9..2ba1b0a6 100644 --- a/frame.js +++ b/frame.js @@ -99,7 +99,7 @@ Volcanos(chat.ONDAEMON, {_init: function(can, name) { if (can.user.isLocalFile) }) Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { meta.index && (meta.name = meta.index), meta.name = can.core.Split(meta.name||"", "\t .\n").pop()||can.Conf(mdb.NAME) - field = field||can.onappend.field(can, meta.type, meta, target)._target + field = field||can.onappend.field(can, meta.type, meta, target)._target, meta.style == "output" && can.onappend.style(can, "output", field) var legend = can.page.SelectOne(can, field, html.LEGEND); legend.innerHTML = legend.innerHTML || meta.index var option = can.page.SelectOne(can, field, html.FORM_OPTION) var action = can.page.SelectOne(can, field, html.DIV_ACTION) @@ -533,7 +533,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { Volcanos(chat.ONLAYOUT, {_init: function(can, target) { target = target||can._root._target; var height = can.page.height(), width = can.page.width() can.page.SelectChild(can, target, can.page.Keys(html.FIELDSET_HEAD, html.FIELDSET_FOOT), function(field) { height -= field.offsetHeight }) can.page.SelectChild(can, target, html.FIELDSET_LEFT, function(field) { can.user.isMobile || can.page.isDisplay(field) && (width -= field.offsetWidth) - var h = height; can.page.SelectChild(can, field, html.DIV_ACTION, function(action) { h -= action.offsetHeight }) + var h = height; can.page.SelectChild(can, field, html.DIV_ACTION, function(action) { h -= action.offsetHeight }), can.user.isMobile || (h -= 160-32) can.page.SelectChild(can, field, html.DIV_OUTPUT, function(output) { can.page.styleHeight(can, output, h) }) }) can.page.SelectChild(can, target, html.FIELDSET_MAIN, function(field) { @@ -565,7 +565,7 @@ Volcanos(chat.ONLAYOUT, {_init: function(can, target) { target = target||can._ro var layout = right? {left: rect.right, top: rect.top}: {left: rect.left, top: rect.bottom} can.getActionSize(function(left, top, width, height) { left = left||0, top = top||0, height = can.base.Max(height, can.page.height()-top) if (can.user.isMobile) { - if (target.offsetHeight > height/2) { layout.top = top+32 } + if (target.offsetHeight > height/2) { layout.top = top } if (target.offsetWidth > width/2) { layout.left = left, can.page.style(can, target, html.WIDTH, width) } } if (layout.top+target.offsetHeight > top+height) { diff --git a/index.css b/index.css index 5eb459c6..62e614a9 100644 --- a/index.css +++ b/index.css @@ -38,8 +38,14 @@ body { --code-constant:gray; --code-string:orange; --code-object:silver; --svg-stroke-width:1; --desktop-icon-size:80px; --project-width:230px; + --button-margin:10px; +} +body.mobile { + --button-margin:5px; +} +body.windows { + --code-font-family:"Courier New"; } -body.windows { --code-font-family:"Courier New"; } /* element */ * { tab-size:4; box-sizing:border-box; padding:0; border:0; margin:0; } legend { padding:0 20px; } @@ -62,7 +68,7 @@ table.content td { padding:5px; } table.content.detail td:first-child { width:80px; } table.content.action th:last-child { position:sticky; right:2px; } table.content.action td:last-child { position:sticky; right:2px; text-align:center; } -table.content input:not(:last-child) { margin-right:10px; } +table.content input:not(:last-child) { margin-right:var(--button-margin); } table.content col.time { width:180px; } table.content col.action { width:200px; } table.content:hover col.option { background-color:var(--hover-bg-color); } @@ -78,14 +84,14 @@ iframe { height:420px; width:100%; } /* fieldset */ fieldset>legend { box-shadow:var(--box-shadow); } fieldset>legend>i { margin-right:5px; } -fieldset>form.option>div.item:not(.icon) { margin-right:10px; box-shadow:var(--box-shadow); } +fieldset>form.option>div.item:not(.icon) { margin-right:var(--button-margin); box-shadow:var(--box-shadow); } fieldset>form.option>div.item.text.cmd { width:100%; } fieldset>form.option>div.item.text.cmd>input { background-color:var(--code-bg-color); color:var(--code-fg-color); width:100%; } fieldset>form.option>div.item.textarea { width:100%; height:96px; } fieldset>form.option>div.item.select { border-radius:5px; } fieldset>form.option>div.item.select>input { min-width:80px; } fieldset>form.option>div.item.button { border-radius:5px; } -fieldset>div.action>div.item { margin-right:10px; box-shadow:var(--box-shadow); } +fieldset>div.action>div.item { margin-right:var(--button-margin); box-shadow:var(--box-shadow); } fieldset>div.action>div.item.select:not(.cmds) { border-radius:5px; } fieldset>div.action>div.item.cmds.select { border-bottom:var(--notice-bg-color) solid 2px; height:32px; } fieldset>div.action>div.item.button { border-radius:5px; } @@ -190,7 +196,7 @@ body:not(.windows) div.tabs { font-family:monospace; } body:not(.windows) div.path { font-family:monospace; } body:not(.windows) div.carte { font-family:monospace; } /* icon */ -div.item>i:first-child { margin-right:10px; } +div.item>i:first-child { margin-right:var(--button-margin); } div.project div.item>i:first-child { color:var(--panel-output-fg-color); } div.project div.item.text:hover>i:first-child { color:var(--plugin-fg-color); } div.action div.icon, div.action>div.item:not(.tabs)>span.icon { font-size:20px; line-height:32px; padding:0 5px; margin:0; height:32px; display:inline-block; } @@ -301,7 +307,7 @@ div.output.card>div.item { background:var(--plugin-bg-color); padding:10px; bord div.output.card>div.item>div.title { font-size:1.2rem; font-weight:bold; padding:10px; border-bottom:var(--box-border); } div.output.card>div.item>div.content { padding:10px; height:70px; } div.output.card>div.item>div.action { text-align:right; width:100%; display:flex; } -div.output.card>div.item>div.action>input { margin-right:5px; box-shadow:var(--box-shadow); } +div.output.card>div.item>div.action>input { margin-right:var(--button-margin); box-shadow:var(--box-shadow); } input[type=button].danger:hover { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } input[type=button].notice:hover { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } /* display */ @@ -326,7 +332,7 @@ div.output.flex { display:flex; overflow:hidden; } div.output>div.code { position:sticky; left:0; } fieldset>div.status>legend { border-radius:0; border-bottom-left-radius:10px; border-bottom-right-radius:10px; box-shadow:var(--box-shadow); - margin-right:5px; float:right; clear:none; + margin-right:var(--button-margin); float:right; clear:none; } fieldset>div.status>legend>span.remove { margin-left:5px; } fieldset>div.status>legend>span.remove:hover { background-color:var(--hover-bg-color); } @@ -407,16 +413,17 @@ div.carte div.item.notice:hover { background-color:var(--notice-bg-color); color /* mobile */ body.cmd.mobile { overflow:hidden; } body.mobile table.content { width:100%; } -body.mobile form.option>div.item { margin:0; } +body.mobile form.option>div.item { margin-right:var(--button-margin); } +body.mobile table.content input:not(:last-child) { margin-right:var(--button-margin); } body.mobile:not(.cmd) form.option>div.item.button>input { display:none; } body.mobile fieldset>div.status { max-height:32px; overflow:hidden; } -body.mobile:not(.cmd) fieldset:not(.panel):not(.input):not(.play)>div.action>div:not(.icons) { display:none; } -body.mobile fieldset>div.action>div.item { margin-right:5px; } +/* body.mobile:not(.cmd) fieldset:not(.panel):not(.input):not(.play)>div.action>div:not(.icons) { display:none; } */ +body.mobile fieldset>div.action>div.item { margin-right:var(--button-margin); } body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd)>form.option>div.icon:not(.delete) { display:block; } body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd)>form.option>div.button>span.icon { display:block; } body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd)>div.action>div.button>span.icon { display:inline-block; } -body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd)>div.action>div.button>input { display:none; } -body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd) { margin:10px 0; } +/* body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd)>div.action>div.button>input { display:none; } */ +/* body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd) { margin:10px 0; } */ body.mobile { --header-height:48px; } body.mobile fieldset.Header { padding:0; width:100%; position:fixed; top:0; } body.mobile fieldset.Header>div.output { font-size:1.4rem; line-height:var(--header-height); height:var(--header-height); } @@ -425,15 +432,15 @@ body.mobile fieldset.Header div.output div.item:not(.avatar) { padding:0px 10px; body.mobile fieldset.Search>div.action>div.item.filter>input { width:100%; } body.mobile fieldset.Search>div.action>div.item.filter>span { position:absolute; } body.mobile fieldset.Search>div.action>div.item.filter { width:100%; position:relative; } -body.mobile fieldset.Search>div.output>div.content { height:400px; } +/* body.mobile fieldset.Search>div.output>div.content { height:400px; } */ body.mobile fieldset.River { position:fixed; top:var(--header-height); z-index:100; } body.mobile fieldset.River>div.output { font-size:1.4rem; min-width:240px; } body.mobile fieldset.Action { margin-top:var(--header-height); } body.mobile fieldset.Action.cmd { margin-top:0; } body.mobile fieldset.Action>div.output { overflow-x:hidden; } -body.mobile fieldset.Action>div.output>fieldset.plugin:not(.float):not(.full):not(.cmd)>legend { margin:10px; } +/* body.mobile fieldset.Action>div.output>fieldset.plugin:not(.float):not(.full):not(.cmd)>legend { margin:10px; } */ body.mobile fieldset.Action>div.output>fieldset.plugin:not(.output):not(.float):not(.full):not(.cmd) { padding:0px; } -body.mobile fieldset.Footer { display:none; } +/* body.mobile fieldset.Footer { display:none; } */ body.mobile.landscape fieldset.Header { position:unset; } body.mobile.landscape fieldset.Action { margin-top:0; } body.mobile fieldset.word.float>div.output>div.project { top:32px; } @@ -468,6 +475,8 @@ fieldset.input.icon div.output td { font-size:28px; padding:5px; } fieldset.Search div.story[data-type=spark] { margin:0; } fieldset.Search>div.output>div.profile { border-left:none; width:unset; } fieldset.Action>div.output>fieldset.plugin:not(.output):not(.float):not(.full):not(.cmd) { padding:10px; margin:10px; box-shadow:var(--box-shadow); } +body.mobile fieldset.Action>div.output>fieldset.plugin:not(.output):not(.float):not(.full):not(.cmd) { padding:10px; margin:10px 0; box-shadow:var(--box-shadow); } +body.mobile fieldset.Action>div.output>fieldset.plugin:not(.output):not(.float):not(.full):not(.cmd):not(:first-child) { margin:20px 0; } fieldset.Action>div.output>fieldset.plugin:not(.float):not(.full):not(.cmd)>legend { float:none; } fieldset.cmd>div.item.time { line-height:22px; padding:5px 10px; float:right; } fieldset.cmd>div.item.avatar { padding:0; height:32px; float:right; } @@ -485,7 +494,7 @@ fieldset.dream>div.output.card>div.item>div.title>span { line-height:48px; marg fieldset.inner.float>div.status { display:none; } fieldset.trans>div.output>fieldset{ margin:10px; } fieldset.trans>form.option>div.item.text>input { width:240px; } -/* fieldset.inner>form.option input[name=path] { width:80px !important; } */ +/* fieldset.inner>form.option input[name=path] { width:120px !important; } */ /* fieldset.inner>form.option input[name=file] { width:160px !important; } */ fieldset.web.code.git>div.output>fieldset.web.code.inner>div.output { overflow:auto; } fieldset.inner>div.output>div.project div.item.modify { background-color:#00800036; } @@ -503,7 +512,7 @@ fieldset.web.code.git.status>div.output table.content { width:100%; } fieldset.web.chat.iframe>form.option input[name=hash] { width:320px; } fieldset.can.view { font-size:14px; } fieldset.can.data { font-size:14px; } -fieldset.word>form.option>div.item>input[name=path] { width:320px !important; } +body:not(.mobile) fieldset.word>form.option>div.item>input[name=path] { width:320px !important; } fieldset.plan div.output div.content>table.content { height:100%; width:100%; } fieldset.plan>div.output>div.layout>div.layout>div.profile:not(.toggle) { width:unset; } fieldset.plan>div.output>div.layout>div.layout>div.profile input { box-shadow:var(--box-shadow); } diff --git a/lib/misc.js b/lib/misc.js index 122a0f05..247a0c88 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -191,7 +191,7 @@ Volcanos("misc", { SearchHash: function(can) { var hash = location.hash if (arguments.length > 1) { hash = can.core.List(arguments, function(item) { return can.base.replaceAll(item, ":", "%3A") }).slice(1).join(nfs.DF) - if (can.isCmdMode() || can._name == "Action") { location.hash = hash } + if (can.isCmdMode() || can._name == "River" || can._name == "Action") { location.hash = hash } } return can.core.List(can.core.Split(can.base.trimPrefix(location.hash, "#"), nfs.DF)||[], function(item) { return decodeURIComponent(item) }) }, diff --git a/lib/user.js b/lib/user.js index b379d771..23bdf35b 100644 --- a/lib/user.js +++ b/lib/user.js @@ -159,7 +159,8 @@ Volcanos("user", { ], onmouseenter: subs, onclick: subs} } return item - })}]); can.onkeymap.prevent(event), can.page.Select(can, ui._target, html.IMG, function(target) { target.onload = function() { can.onlayout.figure(event, can, ui._target) } }) + })}]); can.onkeymap.prevent(event), can.page.Select(can, ui._target, html.IMG, function(target) { target.onload = function() { + can.onlayout.figure(event, can, ui._target) } }) var carte = {_target: ui._target, _parent: parent, layout: can.onlayout.figure(event, can, ui._target, parent, 200), close: function() { can.page.Remove(can, ui._target) }} return parent && (parent._sub = carte), carte }, diff --git a/panel/action.css b/panel/action.css index 54d727e1..cc09424f 100644 --- a/panel/action.css +++ b/panel/action.css @@ -27,3 +27,4 @@ fieldset.Action.vertical>div.project.toggle { display:none; } fieldset.Action.horizon>div.project.toggle { display:none; } fieldset.Action.free>div.project.toggle { display:none; } fieldset.Action.grid>div.project.toggle { display:none; } +body.mobile fieldset.Action>div.project.toggle { top:60%; } diff --git a/panel/action.js b/panel/action.js index 7a9c6a55..08b20005 100644 --- a/panel/action.js +++ b/panel/action.js @@ -1,6 +1,9 @@ (function() { const TABS = "tabs", TABVIEW = "tabview", HORIZON = "horizon", VERTICAL = "vertical", GRID = "grid", FREE = "free", FLOW = "flow", PAGE = "page", CAN_LAYOUT = "can.layout" Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM), list = can.misc.SearchHash(can) can.onmotion.clear(can), can.core.Next(msg.Table(), function(item, next) { item.type = chat.PLUGIN, item.mode = can.Mode(); if (item.deleted == ice.TRUE) { return next() } + item.width = can.ConfWidth()-can.Conf(html.MARGIN_X) + if (item.style == "output") { item.width = can.ConfWidth() } + if (msg.Length() == 1) { item.height = can.ConfHeight()-html.ACTION_HEIGHT-4*html.PLUGIN_MARGIN } can.onappend.plugin(can, item, function(sub, meta, skip) { can._plugins = (can._plugins||[]).concat([sub]), can.onimport._tabs(can, sub, meta), skip || next() sub.onaction._close = function() { can.onengine.signal(can, chat.ONACTION_REMOVE, can.request({river: river, storm: storm}, item)), can.page.Remove(can, sub._target) } sub.run = function(event, cmds, cb) { return can.run(event, [river, storm, meta.id||meta.index].concat(cmds), cb) } @@ -26,7 +29,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.R }, }) Volcanos(chat.ONACTION, {_init: function(can, target) { - can.Conf(html.MARGIN_Y, 4*html.PLUGIN_MARGIN+html.ACTION_HEIGHT), can.Conf(html.MARGIN_X, (can.user.isMobile? 2: 4)*html.PLUGIN_MARGIN) + can.Conf(html.MARGIN_Y, (can.user.isMobile? 0: 4)*html.PLUGIN_MARGIN+html.ACTION_HEIGHT), can.Conf(html.MARGIN_X, (can.user.isMobile? 2: 4)*html.PLUGIN_MARGIN) can.core.List(["ontouchstart", "ontouchmove", "ontouchend"], function(item) { can.onengine.listen(can, item, function(event, msg) { can.onaction[item](event, can), can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }, target) }) @@ -99,7 +102,10 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { layout: function(can, button, skip) { can.page.ClassList.del(can, can._target, can._layout||can.onlayout._storage(can)), can._header_tabs && can.onmotion.hidden(can, can._header_tabs) button = (can.onlayout._storage(can, can._layout = button == ice.AUTO? "": button))||can.misc.SearchOrConf(can, html.LAYOUT), can.page.ClassList.add(can, can._target, button) can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {layout: button})), can._root.River && can._river_show === false && can.onmotion.hidden(can, can._root.River._target), skip || can.onlayout._init(can) - can.isCmdMode() || can.core.List(can._plugins, function(sub) { sub._delay_refresh = false, can.page.ClassList.set(can, sub._target, html.OUTPUT, [TABVIEW, HORIZON, VERTICAL].indexOf(button) > -1) }) + can.isCmdMode() || can.core.List(can._plugins, function(sub) { + sub._delay_refresh = false + // can.page.ClassList.set(can, sub._target, html.OUTPUT, [TABVIEW, HORIZON, VERTICAL].indexOf(button) > -1) + }) var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can) || can.onlayout._plugin(can, button) }, _menus: [[html.LAYOUT, ice.AUTO, TABS, TABVIEW, HORIZON, VERTICAL, GRID, FREE, FLOW, PAGE], "desktop", "dream", "repos", "portal"], @@ -123,6 +129,8 @@ Volcanos(chat.ONLAYOUT, { flow: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-html.ACTION_MARGIN), can.ConfWidth(width) }) }, page: function(can) { can.page.styleHeight(can, can._output, ""), can.page.style(can, document.body, kit.Dict(html.OVERFLOW, "")) }, _plugin: function(can, button) { can.core.List(can._plugins, function(sub) { + if (can.page.ClassList.has(can, sub._target, "output")) { return sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), true) } + if (can._plugins.length == 1) { return sub.onimport.size(sub, can.ConfHeight()-html.ACTION_HEIGHT-4*html.PLUGIN_MARGIN, can.ConfWidth()-can.Conf(html.MARGIN_X), true) } sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y)-(button || sub.isCmdMode()? 0: html.ACTION_MARGIN), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can)) && can.page.style(can, sub._output, html.MAX_HEIGHT, "") }) }, @@ -151,7 +159,10 @@ Volcanos(chat.ONENGINE, {_engine: function(event, sup, msg, can, cmds, cb) { var storm = can.core.Value(can._root, can.core.Keys(chat.RIVER, cmds[0], chat.STORM, cmds[1])); if (!storm || cmds.length != 2) { return false } if (storm.index) { can.runAction(event, ctx.COMMAND, [].concat(can.core.List(storm.index, function(item) { return item.index||item })), function(msg) { - can.core.List(storm.index, function(item) { msg.Push(ctx.ARGS, JSON.stringify(item.args||[])) }), cb(msg) + can.core.List(storm.index, function(item) { + msg.Push(ctx.ARGS, JSON.stringify(item.args||[])) + msg.Push(ctx.STYLE, item.style||"") + }), cb(msg) }) } else { can.core.List(storm.list, function(value) { can.base.isString(value) && (value = {index: value}) msg.Push(mdb.NAME, value.name||"").Push(mdb.HELP, value.help||"").Push(ctx.INPUTS, JSON.stringify(value.inputs)).Push(ctx.FEATURE, JSON.stringify(value.feature)) diff --git a/panel/footer.css b/panel/footer.css index fce1b25c..6e5693e5 100644 --- a/panel/footer.css +++ b/panel/footer.css @@ -9,6 +9,12 @@ fieldset.Footer>div.output div.cmd>i { padding:7px; position:absolute; } fieldset.Footer>div.output div.cmd>input[name=cmd] { padding-left:30px; width:120px; transition:all 1s; } fieldset.Footer>div.output div.cmd>input[name=cmd]:focus { width:320px; transition:all 0.5s; } fieldset.Footer>div.output div.cmd>span.delete { padding:6px; } +fieldset.Footer>div.output div.menu>div.River { display:flex; justify-content:space-around; } +fieldset.Footer>div.output div.menu>div.River>div.item { display:flex; flex-direction:column; text-align:center; flex-grow:1; } +fieldset.Footer>div.output div.menu>div.River>div.item>i { font-size:24px; margin-right:0; } +fieldset.Footer>div.output div.menu>div.River>div.item>span { font-size:12px; } +body.mobile fieldset.Footer>div.output { font-style:italic; height:60px; overflow:hidden; } +body.mobile fieldset.Footer>div.output div.cmd { display:none; } .picker { box-shadow:4px 4px 20px 4px #626bd0; } div.view span.keyword { color:#5cadd4; } diff --git a/panel/footer.js b/panel/footer.js index 6e1aaa42..af98c803 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -2,12 +2,16 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.Conf(NKEY, can.core.Item(can.misc.localStorage(can)).length) can._wss = can.ondaemon._init(can); if (can.user.mod.isCmd) { return } can.Conf("version", can.base.trimPrefix(window._version, "?_v=")) can.onimport._title(can, msg, target), can.onimport._command(can, msg, target) + can.onimport._storm(can, msg, target) can.onimport._state(can, msg, target), can.onimport._toast(can, msg, target) }, _title: function(can, msg, target) { can.user.isMobile || can.core.List(can.Conf(chat.TITLE)||msg.result, function(item) { if (can.base.contains(item, ice.AT)) { item = ''+item+'' } can.page.Append(can, target, [{view: [[html.ITEM, chat.TITLE], "", item], title: "联系站长"}]) }) }, + _storm: function(can, msg, target) { + can.ui.storm = can.page.Append(can, can._output, ["menu"])._target + }, _state: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [NTIP, NLOG, NCMD, NKEY, "version"]).reverse(), function(item) { can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE]], list: [ {text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", "", item]}, @@ -28,13 +32,23 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.Conf(NKEY, can. ntip: function(can, msg, time, title, content) { can.onimport._data(can, NTIP, {time: time, fileline: can.base.trimPrefix(msg.Option("log.caller"), location.origin+nfs.PS), title: title, content: content}), can.page.Modify(can, can.ui.toast, [time, title, content].join(lex.SP)) }, ncmd: function(can, msg, _follow, _cmds) { can.onimport._data(can, NCMD, {time: can.base.Time(), follow: _follow, cmds: _cmds}), can.onimport.nlog(can, NLOG) }, nlog: function(can, name) { can.onimport.count(can, name) }, + menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds]) + return can.page.Append(can, can.ui.storm, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) { + return {view: [[html.ITEM, item.name]], list: [{icon: item.icon}, {text: item.name}], onclick: function(event) { + can.onmotion.select(can, event.currentTarget.parentNode, html.DIV_ITEM, event.currentTarget) + cb(event, item.hash) + }} + }) }])._target + }, }) Volcanos(chat.ONACTION, {_init: function(can) {}, onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, onlogin: function(can, msg) { can.run(can.request({}, {_method: http.GET}), [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) }, ontoast: function(can, msg) { can.core.CallFunc(can.onimport.ntip, {can: can, msg: msg}) }, onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) }, - onlayout: function(can, layout) { can.onmotion.toggle(can, can._target, !layout || layout == html.TABS) }, + onlayout: function(can, layout) { + // can.onmotion.toggle(can, can._target, !layout || layout == html.TABS) + }, onunload: function(can) { can._wss && can._wss.close() }, onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, oncommand_focus: function(can) { can.page.Select(can, can._output, ["div.cmd", html.INPUT], function(target) { can.onmotion.focus(can, target) }) }, diff --git a/panel/header.css b/panel/header.css index e4d1fc2e..71a103c5 100644 --- a/panel/header.css +++ b/panel/header.css @@ -3,7 +3,8 @@ fieldset.Header>div.output div.item { background-color:var(--panel-output-bg-col fieldset.Header>div.output div.title:first-child { font-style:italic; font-weight:bold; text-align:center; width:var(--project-width); overflow:auto; } fieldset.Header>div.output div.state { float:right; } fieldset.Header>div.output div.state.avatar { padding:0; } -fieldset.Header>div.output div.state.avatar>img { height:48px; } +body.mobile fieldset.Header>div.output div.state.avatar { margin-right:10px; } +fieldset.Header>div.output div.state.avatar>img { height:48px; clip-path:circle(40%); } fieldset.Header>div.output div.search.title { padding:8px 5px; margin-left:5px; position:relative; } fieldset.Header>div.output div.search>i { padding:6px; position:absolute; } fieldset.Header>div.output div.search>input { padding-left:30px; transition:all 1s; } diff --git a/panel/header.js b/panel/header.js index 654f57ac..c85acee4 100644 --- a/panel/header.js +++ b/panel/header.js @@ -92,7 +92,10 @@ Volcanos(chat.ONACTION, {_init: function(can) { }, carte: function(event, can, list, cb, trans) { return can.user.carte(event, can, can.onaction, list, cb, null, trans) }, share: function(event, can, args) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(args||[])) }, - avatar: function(event, can) { can.onaction.carte(event, can, [can.page.Format(html.IMG, can.onexport.avatar(can), can.page.height()/2)]) }, + avatar: function(event, can) { var src = can.onexport.avatar(can) + can.onaction.carte(event, can, [ + can.user.isMobile? ``: can.page.Format(html.IMG, src, can.page.height()/2) + ]) }, usernick: function(event, can) { can.onaction.carte(event, can, can.onaction._menus) }, shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN, mdb.NAME, can.user.title(), mdb.TEXT, location.href]) }, toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) }, diff --git a/panel/river.css b/panel/river.css index 8da63a2f..72248478 100644 --- a/panel/river.css +++ b/panel/river.css @@ -1,6 +1,7 @@ fieldset.River { width:var(--project-width); float:left; } fieldset.River>div.action { width:100%; display:flex; justify-content:center; } -fieldset.River>div.output { padding:40px 10px; } fieldset.River>div.output div.item { padding:20px 20px; border-left:#00ffae solid 3px; } fieldset.River>div.output div.list div.item { border-left:#ccdc4c solid 3px; } fieldset.River>div.output div.list { margin-left:20px; } +body:not(.mobile) fieldset.River>div.output { padding:10px; } +body:not(.mobile) fieldset.River>div.output { margin:80px 0; } diff --git a/panel/river.js b/panel/river.js index b19eb6d0..5d2f9cde 100644 --- a/panel/river.js +++ b/panel/river.js @@ -17,7 +17,10 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onimport._main(can, msg } }, _menu: function(can, msg) { can.user.isMobile || can.user.mod.isPod || can.onappend._action(can, can.onaction.list, can._action) }, }) -Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.SHARE, web.REFRESH], _init: function(can) { can.onmotion.hidden(can) }, +Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.SHARE, web.REFRESH], _init: function(can) { + can.db.storm_list = {} + can.onmotion.hidden(can) + }, onlogin: function(can, msg) { can.run(can.request({}, {_method: http.GET}), [], function(msg) { if (msg.Option(ice.MSG_RIVER)) { return can.page.Remove(can, can._target) } can.onimport._init(can, msg); if (can.user.isMobile || can.user.isExtension) { return can.page.ClassList.add(can, can._target, ice.AUTO) } can.onmotion.toggle(can, can._target, true), can.onlayout._init(can) @@ -37,16 +40,23 @@ Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.SHARE, web.REFRESH], _init: func }) }, share: function(event, can) { can.core.CallFunc(can.ondetail.share, {event: event, can: can}) }, refresh: function(event, can) { can.misc.Search(can, {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM)}) }, - storm: function(event, can, river) { can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river]) - var list = can.ui.sublist[river]; if (list) { return can.onmotion.toggle(can, list) } + storm: function(event, can, river) { + can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river]) + function _menu() { can.user.isMobile && can.onmotion.delay(can, function() { var list = can.db.storm_list[river] + can.onmotion.hidden(can, can._root.Footer._target, list.length > 1) + var menu = can.setFooterMenu(list, function(event, button, list) { can.onaction.action(event, can, river, button) }) + can.page.SelectChild(can, menu, html.DIV_ITEM, function(target, index) { can.page.ClassList.set(can, target, html.SELECT, list[index].hash == can.Conf("storm")) }) + }) } + var list = can.ui.sublist[river]; if (list) { return can.onmotion.toggle(can, list), _menu() } can.run({}, [river, chat.STORM], function(msg) { var next = can.ui.river_list[river].nextSibling if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOSTORM, can.request({}, {river: river})) } + can.db.storm_list[river] = msg.Table() var select = 0; list = can.page.Append(can, can._output, [{view: html.LIST, list: msg.Table(function(item, index) { return river == can._main_river && item.hash == can._main_storm && (select = index), can.onimport._storm(can, item, river) - }) }])._target, next && can._output.insertBefore(list, next), can.ui.sublist[river] = list, list.children.length > 0 && list.children[select].click() + }) }])._target, next && can._output.insertBefore(list, next), can.ui.sublist[river] = list, _menu(), list.children.length > 0 && list.children[select].click() }) }, - action: function(event, can, river, storm) { + action: function(event, can, river, storm) { can.misc.SearchHash(can, river, storm) can.page.Select(can, can._output, [html.DIV_LIST, html.DIV_ITEM], function(target) { can.page.ClassList.del(can, target, html.SELECT) }) can.onmotion.select(can, can.ui.sublist[river], html.DIV_ITEM, can.ui.storm_list[can.core.Keys(river, storm)]) can.onaction.storm({target: can.ui.river_list[river]}, can, river), can.onmotion.toggle(can, can.ui.sublist[river], true) diff --git a/panel/search.js b/panel/search.js index bf1a163f..55311fae 100644 --- a/panel/search.js +++ b/panel/search.js @@ -1,12 +1,13 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can, can.ui.content) var table = can.onappend.table(can, msg, function(value, key, index, data) { return {text: [can.base.isFunc(value) && value.help || value, html.TD], onclick: function(event) { - can.page.tagis(event.target, html.A) || can.onaction[can.db.type == mdb.FOREACH || event.ctrlKey? mdb.PLUGIN: mdb.SELECT](event, can, data) + can.page.tagis(event.target, html.A) || can.onaction[can.db.type == mdb.FOREACH || event.ctrlKey? mdb.PLUGIN: mdb.SELECT](event, can, data) }} }, can.ui.content, msg.append); can.onmotion.story.auto(can), can.onimport._size(can) can.onmotion.toggle(can, can._status, can.db.type != mdb.FOREACH) && can.onappend._status(can, can.base.Obj(msg.Option(ice.MSG_STATUS), []).concat({name: mdb.SELECT, value: "0"})) can.onmotion.focus(can, can.ui.filter), msg.Length() == 1 && can.ui.profile.innerHTML == "" && can.page.Select(can, table, html.TD)[0].click() }, _size: function(can) { can.ui && can.ui.content && can.getActionSize(function(left, top, width, height) { - can.page.style(can, can._target, {left: left||0, top: top||0, width: width}), can.page.style(can, can._output, html.MAX_HEIGHT, height -= 2*html.PLUGIN_MARGIN+html.ACTION_HEIGHT+can.onexport.statusHeight(can)) + can.page.style(can, can._target, {left: left||0, top: top||0, width: width}), + can.page.style(can, can._output, html.MAX_HEIGHT, height -= 2*html.PLUGIN_MARGIN+(can.user.isMobile? 2: 1)*html.ACTION_HEIGHT+can.onexport.statusHeight(can)) can.core.List([can.ui.content, can.ui.display], function(target) { can.page.style(can, target, html.MAX_WIDTH, can.ConfWidth(width-2*html.PLUGIN_MARGIN)) }) can.ConfHeight(can.base.Min(height-can.ui.content.offsetHeight-can.ui.display.offsetHeight-1, height/2)) }) }, @@ -55,13 +56,17 @@ Volcanos(chat.ONACTION, {_init: function(can) { can.onmotion.hidden(can) }, list if (data.type == nfs.FILE) { meta = {index: web.CODE_VIMER, args: can.misc.SplitPath(can, data.text)} } if (data.type == nfs.SHY) { meta = {index: web.WIKI_WORD, args: data.text} } if (data.type == ice.CMD) { meta = {index: data.name, args: can.core.Split(data.text)} } + function plugin(meta) { can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub) + can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, can.ui.profile) }, 500) + sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth()-1, true) + }, can.ui.profile) } if (data.ctx == ice.NFS && data.cmd == nfs.PACK) { var ls = can.misc.SplitPath(can, data.text) can.runAction(event, ctx.RUN, [web.CODE_VIMER, ctx.ACTION, mdb.RENDER, data.type, ls[1], ls[0]], function(msg) { msg.Table(function(meta) { - can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub), sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth()-1, true) }, can.ui.profile) + plugin(meta) }), can.onappend.board(can, msg.Result(), can.ui.profile) }) - return + } else { + plugin(meta) } - can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub), sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth()-1, true) }, can.ui.profile) }, }) Volcanos(chat.ONEXPORT, {statusHeight: function(can) { return can.db && can.db.type == mdb.FOREACH? 0: html.ACTION_HEIGHT }, diff --git a/plugin/input/icons.js b/plugin/input/icons.js index 57454c4a..62e3851b 100644 --- a/plugin/input/icons.js +++ b/plugin/input/icons.js @@ -17,6 +17,18 @@ Volcanos(chat.ONFIGURE, {icons: { target._icon = target._icon || can.page.insertBefore(can, [{type: "i"}], target) 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) }) }, - onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) }, + // onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) }, + onkeyup: function(event, can, sub, cb) { if (!sub) { return } + can.page.Select(can, sub._output, html.TD, function(target) { + can.onmotion.hidden(can, target, target.title.indexOf(event.target.value) > -1) + }) + can.page.Select(can, sub._output, html.TR, function(target) { + can.onmotion.hidden(can, target, + can.page.Select(can, target, html.TD, function(target) { + if (!can.page.ClassList.has(can, target, html.HIDE)) { return target } + }).length > 0 + ) + }) + }, }}) diff --git a/plugin/local/mall/goods.css b/plugin/local/mall/goods.css index 02a743a8..2c38a04f 100644 --- a/plugin/local/mall/goods.css +++ b/plugin/local/mall/goods.css @@ -1,8 +1,12 @@ -fieldset.goods>div.output>div.project { flex:0 0 80px; } +fieldset.goods>div.output>div.project { flex:0 0 76px; } fieldset.goods>div.output>div.project>div.item { text-align:center; padding:20px 10px; border-right:var(--plugin-bg-color) solid 4px; } +fieldset.goods>div.output>div.project>div.item.select { border-right:var(--notice-bg-color) solid 4px; } fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) { background-color:var(--plugin-bg-color); border-radius:10px; box-shadow:var(--box-shadow); - margin:10px; float:left; display:flex; height:150px; + margin:10px; float:left; display:flex; +} +body:not(.mobile) fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) { + height:150px; } fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div { padding:10px; float:left; clear:none; } fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.image { flex-grow:0; } diff --git a/plugin/local/mall/goods.js b/plugin/local/mall/goods.js index 9e4b008f..d8733aea 100644 --- a/plugin/local/mall/goods.js +++ b/plugin/local/mall/goods.js @@ -30,8 +30,8 @@ Volcanos(chat.ONIMPORT, { } }) } }, - layout: function(can) { - can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight()) - can.ui.content && can.onlayout.expand(can, can.ui.content, 260) + layout: function(can) { if (!can.ui.content) { return } + can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()-can.ui.project.offsetWidth) + can.onlayout.expand(can, can.ui.content, 260) }, }, [""]) diff --git a/proto.js b/proto.js index c62d3a2b..6f29c50d 100644 --- a/proto.js +++ b/proto.js @@ -76,7 +76,10 @@ var Volcanos = shy({iceberg: "", volcano: "", frame: chat.FRAME_JS, _cache: {}, get: function(name, key, cb) { var value; can.search({}, [can.core.Keys(name, chat.ONEXPORT, key)], cb||function(msg) { value = msg.Result() }); return value }, set: function(name, key, value) { var msg = can.request(); msg.Option(key, value); return can.search(msg, [[name, chat.ONIMPORT, key]]) }, setHeaderMenu: function(list, cb) { can._menu && can.page.Remove(can, can._menu) - return can._menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.HEADER, chat.ONIMPORT, html .MENU], can._name].concat(list), cb) + return can._menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.HEADER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb) + }, + setFooterMenu: function(list, cb) { can._footer_menu && can.page.Remove(can, can._footer_menu) + return can._footer_menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.FOOTER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb) }, getHeaderTheme: function(cb) { return can.get(chat.HEADER, chat.THEME, cb) }, getHeader: function(key, cb) { return can.get(chat.HEADER, key, cb) },