diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 32a9dee9..657a0728 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -145,19 +145,24 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands INPUTS: {Name: "inputs key sub type field value", Hand: func(m *ice.Message, arg ...string) { switch arg[3] { case "space": - m.Cmdy("web.space").Cut(NAME) + m.Cmd("space", func(value ice.Maps) { + kit.If(kit.IsIn(value[TYPE], "worker", "server"), func() { m.Push(arg[3], value[NAME]) }) + }) case "index": - m.Cmdy("command") - return + if space := m.Option("space"); space != "" { + m.Options("space", []string{}).Cmdy("space", space, INPUTS, arg) + } else { + m.Cmdy("command") + } case "args": m.Cmdy("command", INPUTS, m.Option("index")) - return + default: + kit.Switch(arg[2], + HASH, func() { _hash_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) }, + ZONE, func() { _zone_inputs(m, arg[0], arg[1], arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5)) }, + LIST, func() { _list_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) }, + ) } - kit.Switch(arg[2], - HASH, func() { _hash_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) }, - ZONE, func() { _zone_inputs(m, arg[0], arg[1], arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5)) }, - LIST, func() { _list_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) }, - ) }}, INSERT: {Name: "insert key sub type arg...", Hand: func(m *ice.Message, arg ...string) { kit.Switch(arg[2], diff --git a/base/web/dream.go b/base/web/dream.go index 0c94e5a0..086ac07c 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -54,7 +54,7 @@ func _dream_start(m *ice.Message, name string) { if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath), kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { m.Info("already exists %v", pid) return - } else if m.Cmd(SPACE, name).Length() > 0 { + } else if msg := m.Cmd(SPACE, name); msg.Length() > 0 { m.Info("already exists %v", name) return } diff --git a/base/web/space.go b/base/web/space.go index 0cfb43eb..2c94d7fc 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -138,6 +138,7 @@ func _space_send(m *ice.Message, name string, arg ...string) (h string) { m.Cost(kit.Format("%v->[%v] %v %v", m.Optionv(ice.MSG_SOURCE), name, m.Detailv(), msg.FormatSize())).Copy(msg) }) h = mdb.HashCreate(m.Spawn(), mdb.TYPE, tcp.SEND, mdb.NAME, kit.Keys(name, m.Target().ID()), mdb.TEXT, kit.Join(arg, lex.SP), kit.Dict(mdb.TARGET, done)) + defer mdb.HashRemove(m.Spawn(), mdb.HASH, h) if target := kit.Split(name, nfs.PT, nfs.PT); mdb.HashSelectDetail(m, target[0], func(value ice.Map) { if c, ok := value[mdb.TARGET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotValid, mdb.TARGET) { kit.For([]string{ice.MSG_USERROLE}, func(k string) { m.Optionv(k, m.Optionv(k)) }) @@ -220,7 +221,7 @@ func init() { m.Option(ice.MSG_USERWEB, tcp.PublishLocalhost(m, m.Option(ice.MSG_USERWEB))) mdb.HashSelect(m.Spawn(), arg...).Sort("").Table(func(index int, value ice.Maps, field []string) { if kit.IsIn(value[mdb.TYPE], CHROME, "send") { - return + // return } if m.Push("", value, kit.Split(mdb.Config(m, mdb.FIELD))); len(arg) > 0 && arg[0] != "" { m.Push(mdb.STATUS, value[mdb.STATUS]) diff --git a/core/chat/flows.css b/core/chat/flows.css index 055d2a06..cee5e0ac 100644 --- a/core/chat/flows.css +++ b/core/chat/flows.css @@ -1,11 +1,11 @@ body { --web-flows-done:lightgreen; --web-flows-fail:var(--danger-bg-color); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.fail { stroke:var(--web-flows-fail); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.done { stroke:var(--web-flows-done); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.select { stroke:var(--notice-fg-color); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.fail { stroke:var(--web-flows-fail); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.done { stroke:var(--web-flows-done); } +fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.select { stroke:var(--notice-fg-color); } fieldset.web.flows>div.output>div.layout>div.layout>div.content svg text { dominant-baseline:middle; } fieldset.web.flows>div.output>div.layout>div.layout>div.content svg text.fail { stroke:var(--web-flows-fail); fill:var(--web-flows-fail); } fieldset.web.flows>div.output>div.layout>div.layout>div.content svg text.done { stroke:var(--web-flows-done); fill:var(--web-flows-done); } fieldset.web.flows>div.output>div.layout>div.layout>div.content svg text.select { stroke:var(--notice-fg-color); fill:var(--notice-fg-color); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.fail { stroke:var(--web-flows-fail); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.done { stroke:var(--web-flows-done); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg rect.select { stroke:var(--notice-fg-color); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.fail { stroke:var(--web-flows-fail); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.done { stroke:var(--web-flows-done); } -fieldset.web.flows>div.output>div.layout>div.layout>div.content svg line.select { stroke:var(--notice-fg-color); } diff --git a/core/chat/flows.go b/core/chat/flows.go index 29e88807..c391e7be 100644 --- a/core/chat/flows.go +++ b/core/chat/flows.go @@ -12,7 +12,14 @@ const FLOWS = "flows" func init() { Index.MergeCommands(ice.Commands{ FLOWS: {Name: "flows zone hash auto", Help: "工作流", Actions: ice.MergeActions(ice.Actions{ - mdb.INSERT: {Name: "insert space index* args", Hand: func(m *ice.Message, arg ...string) { + mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { + if mdb.IsSearchPreview(m, arg) { + mdb.HashSelect(m.Spawn(ice.OptionFields(""))).Table(func(value ice.Maps) { + m.PushSearch(mdb.TYPE, "", mdb.NAME, value[mdb.ZONE], mdb.TEXT, value[mdb.ZONE], value) + }) + } + }}, + mdb.INSERT: {Name: "insert name space index* args", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.INSERT, m.PrefixKey(), kit.KeyHash(m.Option(mdb.ZONE)), mdb.HASH, m.OptionSimple(mdb.Config(m, mdb.FIELDS))) }}, mdb.DELETE: {Hand: func(m *ice.Message, arg ...string) { @@ -21,7 +28,7 @@ func init() { mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.MODIFY, m.PrefixKey(), kit.KeyHash(m.Option(mdb.ZONE)), mdb.HASH, m.OptionSimple(mdb.HASH), arg) }}, - }, ctx.CmdAction(), mdb.ExportHashAction(), mdb.HashAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,zone", mdb.FIELDS, "time,hash,space,index,args,prev,from,status")), Hand: func(m *ice.Message, arg ...string) { + }, ctx.CmdAction(), mdb.ExportHashAction(), mdb.HashAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,zone", mdb.FIELDS, "time,hash,name,space,index,args,prev,from,status")), Hand: func(m *ice.Message, arg ...string) { if arg = kit.Slice(arg, 0, 2); len(arg) == 0 || arg[0] == "" { mdb.HashSelect(m) } else { diff --git a/core/chat/flows.js b/core/chat/flows.js index beea210d..c4a5b0a4 100644 --- a/core/chat/flows.js +++ b/core/chat/flows.js @@ -4,75 +4,65 @@ Volcanos(chat.ONIMPORT, { if (can.Option(mdb.ZONE)) { return can.onmotion.hidden(can, can.ui.project), can.onimport._content(can, msg, can.Option(mdb.ZONE)) } can.onimport._project(can, msg) }, _project: function(can, msg) { var target; msg.Table(function(value) { - var item = can.onimport.item(can, value, function(event) { + var item = can.onimport.item(can, value, function(event) { can.Option(mdb.ZONE, value.zone) if (can.onmotion.cache(can, function(data, old) { - if (old) { data[old] = { - _content_plugin: can._content_plugin, - _profile_plugin: can._profile_plugin, - toggle: can.ui.toggle, - current: can.ui.current, - root: can.db.root, - list: can.db.list, - } } - var back = data[value.zone]; if (back) { - can._content_plugin = back._content_plugin - can._profile_plugin = back._profile_plugin - can.ui.toggle = back.toggle - can.ui.current = back.current - can.db.root = back.root - can.db.list = back.list - } + if (old) { data[old] = {db: can.db, toggle: can.ui.toggle, _display_class: can.ui.display.className, _profile_class: can.ui.profile.className} } + var back = data[value.zone]||{}; can.db = back.db||{}, can.ui.toggle = back.toggle + can.ui.display.className = back._display_class||can.ui.display.className + can.ui.profile.className = back._profile_class||can.ui.profile.className return value.zone - }, can.ui.content, can.ui.profile, can.ui.display)) { return } - can.run(event, [value.zone], function(msg) { can.onimport._content(can, msg, can.Option(mdb.ZONE, value.zone)) }) + }, can.ui.content, can.ui.display, can._status)) { return can.page.isDisplay(can.ui.profile) && can.onimport._profile(can, can.db.current), can.onimport.layout(can) } + can.run(event, [value.zone], function(msg) { can.onimport._content(can, msg, can.Option(mdb.ZONE)) }) }, null, can.ui.project); target = can.Option(mdb.ZONE) == value.zone? item: target||item }), target && target.click() }, _content: function(can, msg, zone) { if (msg.Length() == 0) { return can.Update(can.request({target: can._legend}, {title: mdb.INSERT, zone: zone}), [ctx.ACTION, mdb.INSERT]) } + can.db.list = {}; msg.Table(function(value) { can.db.list[value.hash] = value }) + var root; can.core.Item(can.db.list, function(key, item) { if (!item.prev && !item.from) { return root = item } + try { + if (item.prev) { can.db.list[item.prev].next = item } if (item.from) { can.db.list[item.from].to = item } + } catch(e) { console.log(e) } + }), can.db.root = root, can.db.current = root + var _list = can.onexport.travel(can, can.db.root, true), _msg = can.request(); can.core.List(_list, function(item) { _msg.Push(item, msg.append) }) + var table = can.onappend.table(can, _msg, null, can.ui.display); can.page.Select(can, table, "tbody>tr", function(target, index) { _list[index]._tr = target }) + can.onappend._status(can, can.base.Obj(msg.Option(ice.MSG_STATUS))) + can.core.Item(can.db.list, function(key, item) { if (item.prev) { item.prev = can.db.list[item.prev] } if (item.from) { item.from = can.db.list[item.from] } }) can.onappend.plugin(can, {index: web.WIKI_DRAW, display: "/plugin/local/wiki/draw.js", style: html.OUTPUT}, function(sub) { can.ui.toggle = can.onappend.toggle(can, can.ui.content) - sub.onexport.output = function(_sub, _msg) { sub.Action(svg.GO, "manual"), sub.Action(ice.MODE, web.RESIZE), can.onmotion.hidden(can, _sub._action) - can.db.list = {}; msg.Table(function(value) { can.db.list[value.hash] = value }) - var root; can.core.Item(can.db.list, function(key, item) { if (!item.prev && !item.from) { return root = item } - if (item.prev) { can.db.list[item.prev].next = item } if (item.from) { can.db.list[item.from].to = item } - }), can.db.root = root, can.ui.current = root, can._content_plugin = _sub - var _list = can.onexport.travel(can, can.db.root, true), _msg = can.request(); can.core.List(_list, function(item) { _msg.Push(item, msg.append) }) - var table = can.onappend.table(can, _msg, null, can.ui.display); can.page.Select(can, table, "tbody>tr", function(target, index) { _list[index]._tr = target }) - can.onappend._status(can, can.base.Obj(msg.Option(ice.MSG_STATUS))), can.onimport.layout(can) - can.core.Item(can.db.list, function(key, item) { if (item.prev) { item.prev = can.db.list[item.prev] } if (item.from) { item.from = can.db.list[item.from] } }) - can.onimport._flows(can, _sub) + sub.onexport.output = function(_sub, _msg) { sub.Action(svg.GO, "manual"), sub.Action(ice.MODE, web.RESIZE), can.onmotion.hidden(can, _sub._action), can.db._content_plugin = _sub + can.onimport.layout(can), can.onimport._flows(can, _sub) }, sub.run = function(event, cmds, cb) { cb(can.request(event)) } }, can.ui.content) }, - _profile: function(can, item) { + _profile: function(can, item) { if (!item.index) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } if (can.onmotion.cache(can, function() { return can.core.Keys(can.Option(mdb.ZONE), item.hash) }, can.ui.profile)) { return can.onmotion.toggle(can, can.ui.profile, true), can.onimport.layout(can) } - can.onappend.plugin(can, {index: item.index, args: item.args, width: can.ui.content.offsetWidth/2-1}, function(sub) { can._profile_plugin = sub - sub.run = function(event, cmds, cb) { can.runActionCommand(event, item.index, cmds, function(msg) { - can.onmotion.toggle(can, can.ui.profile, true), cb(msg) - }) } + can.onappend.plugin(can, {space: item.space, index: item.index, args: item.args, width: (can.ConfWidth()-can.ui.project.offsetWidth)/2-1}, function(sub) { can.db._profile_plugin = sub + sub.run = function(event, cmds, cb) { can.runActionCommand(can.request(event, {pod: item.space}), item.index, cmds, function(msg) { can.onmotion.toggle(can, can.ui.profile, true), cb(msg) }) } sub.onexport.output = function() { can.onmotion.toggle(can, can.ui.profile, true), can.onimport.layout(can) } sub.onaction._close = function() { can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } }, can.ui.profile) }, - _flows: async function(can, _sub) { var margin = can.onexport.margin(can), width = can.onexport.width(can), height = can.onexport.height(can) - var matrix = {}; can.onmotion.clear(can, _sub.svg), can.ui._height = 0, can.ui._width = 0 - var horizon = can.Action("direct") == "horizon" + _flows: async function(can, _sub) { var margin = can.onexport.margin(can), height = can.onexport.height(can), width = can.onexport.width(can) + var matrix = {}, horizon = can.Action("direct") == "horizon"; can.onmotion.clear(can, _sub.svg), can.db._height = 0, can.db._width = 0 async function sleep() { return new Promise(resolve => { setTimeout(resolve, can.Action("delay")) }) } async function show(item, main) { var prev = "from", from = "prev"; if (horizon) { var prev = "prev", from = "from" } while (matrix[can.core.Keys(item.x, item.y)]) { if (horizon && main || !horizon && !main) { item.y++ for(var _item = item[prev]; _item; _item = _item[prev]) { _item.y++ + if (!horizon && _item[prev]) { + _item._line.Val("y1", _item._line.Val("y1")+height) + } _item._line.Val("y2", _item._line.Val("y2")+height) _item._rect.Val("y", _item._rect.Val("y")+height) _item._text.Val("y", _item._text.Val("y")+height) - _item._line.Val("y2", _item._line.Val("y2")+height) } } else { item.x++ for(var _item = item[from]; _item; _item = _item[from]) { _item.x++ + if (horizon && _item[from]) { + _item._line.Val("x1", _item._line.Val("x1")+width) + } _item._line.Val("x2", _item._line.Val("x2")+width) _item._rect.Val("x", _item._rect.Val("x")+width) _item._text.Val("x", _item._text.Val("x")+width) - _item._line.Val("x2", _item._line.Val("x2")+width) } } - } - matrix[can.core.Keys(item.x, item.y)] = item + } matrix[can.core.Keys(item.x, item.y)] = item if (item.from || item.prev) { item._line = _sub.onimport.draw(_sub, {shape: svg.LINE, points: horizon && item.from || !horizon && !item.from? [{x: item.x*width+width/2, y: item.y*height-margin}, {x: item.x*width+width/2, y: item.y*height+margin}]: [{x: item.x*width-margin, y: item.y*height+height/2}, {x: item.x*width+margin, y: item.y*height+height/2}] @@ -87,36 +77,26 @@ Volcanos(chat.ONIMPORT, { } } can.db.root.x = 0, can.db.root.y = 0, await show(can.db.root, true) }, - _block: function(can, _sub, item, x, y) { var margin = can.onexport.margin(can), width = can.onexport.width(can), height = can.onexport.height(can) + _block: function(can, _sub, item, x, y) { var margin = can.onexport.margin(can), height = can.onexport.height(can), width = can.onexport.width(can) var rect = _sub.onimport.draw(_sub, {shape: svg.RECT, points: [{x: x+margin, y: y+margin}, {x: x+width-margin, y: y+height-margin}]}) - var text = _sub.onimport.draw(_sub, {shape: svg.TEXT, points: [{x: x+width/2, y: y+height/2}], style: {inner: item.index.split(nfs.PT).pop()}}) + var text = _sub.onimport.draw(_sub, {shape: svg.TEXT, points: [{x: x+width/2, y: y+height/2}], style: {inner: item.name||item.index.split(nfs.PT).pop()}}) item._rect = rect, item._text = text, can.core.ItemCB(can.ondetail, function(key, cb) { text[key] = rect[key] = function(event) { cb(event, can, _sub, item) } }) - if (item.status) { - item._line && item._line.Value(html.CLASS, item.status) - rect.Value(html.CLASS, item.status) - text.Value(html.CLASS, item.status) - } - if (can.ui._height < y+height) { can.ui._height = y+height, can.onimport.layout(can), can.isCmdMode() && rect.scrollIntoView() } - if (can.ui._width < x+width) { can.ui._width = x+width, can.onimport.layout(can), can.isCmdMode() && rect.scrollIntoView() } + if (item.status) { item._line && item._line.Value(html.CLASS, item.status), rect.Value(html.CLASS, item.status), text.Value(html.CLASS, item.status) } + if (can.db._height < y+height) { can.db._height = y+height, can.onimport.layout(can), can.isCmdMode() && rect.scrollIntoView() } + if (can.db._width < x+width) { can.db._width = x+width, can.onimport.layout(can), can.isCmdMode() && rect.scrollIntoView() } }, layout: function(can) { - if (can.page.isDisplay(can.ui.profile)) { var profile = can._profile_plugin - if (profile) { - can.page.styleWidth(can, can.ui.profile, (can.ConfWidth()-can.ui.project.offsetWidth)/2) - } else { - can.user.toast(can, "nothing to display"), can.onmotion.hidden(can, can.ui.profile) - } - } + if (can.page.isDisplay(can.ui.profile)) { var profile = can.db._profile_plugin; can.page.styleWidth(can, can.ui.profile, (can.ConfWidth()-can.ui.project.offsetWidth)/2) } can.page.isDisplay(can.ui.display) && can.page.SelectChild(can, can.ui.display, html.TABLE, function(target) { can.page.styleHeight(can, can.ui.display, can.base.Max(target.offsetHeight, can.ConfHeight()/2)+1) }) - can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) { - var _sub = can._content_plugin; if (_sub) { _sub.sup.onimport.size(_sub.sup, height, width), _sub.svg.Val(html.HEIGHT, can.ui._height), _sub.svg.Val(html.WIDTH, can.ui._width) } + can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) { can.ui.toggle && can.ui.toggle.layout() + var _sub = can.db._content_plugin; if (_sub) { _sub.sup.onimport.size(_sub.sup, height, width), _sub.svg.Val(html.HEIGHT, can.db._height), _sub.svg.Val(html.WIDTH, can.db._width) } + profile && profile.onimport.size(profile, can.ui.profile.offsetHeight, can.ui.profile.offsetWidth-1, true) }) - profile && profile.onimport.size(profile, can.ui.profile.offsetHeight, can.ui.profile.offsetWidth-1, true) - if (can.ui.toggle) { can.ui.toggle.layout() } }, }, [""]) Volcanos(chat.ONDETAIL, { - _select: function(event, can, item) { if (!item) { return } can.ui.current = item, can.onimport._profile(can, item) + _select: function(event, can, item) { if (!item) { return can.onmotion.hidden(can, can.ui.profile) } + can.isCmdMode() && item._rect.scrollIntoView(), can.db.current = item, can.onimport._profile(can, item) can.page.Select(can, item._rect.parentNode, "", function(target) { var _class = (target.Value(html.CLASS)||"").split(lex.SP) if (can.base.isIn(target, item._line, item._rect, item._text)) { if (_class.indexOf(html.SELECT) == -1) { target.Value(html.CLASS, _class.concat([html.SELECT]).join(lex.SP).trim()) } @@ -124,7 +104,6 @@ Volcanos(chat.ONDETAIL, { if (_class.indexOf(html.SELECT) > -1) { target.Value(html.CLASS, _class.filter(function(c) { return c != html.SELECT }).join(lex.SP).trim()) } } }), can.page.Select(can, item._tr.parentNode, "", function(target) { can.page.ClassList.set(can, target, html.SELECT, target == item._tr) }) - can.isCmdMode() && item._rect.scrollIntoView() }, onclick: function(event, can, _sub, item) { switch (_sub.svg.style.cursor) { case "e-resize": can.Update(can.request(event, can.Action("direct") == "horizon"? {prev: item.hash}: {from: item.hash}), [ctx.ACTION, mdb.INSERT]); break @@ -135,7 +114,7 @@ Volcanos(chat.ONDETAIL, { }) Volcanos(chat.ONACTION, { list: [ - "play", "prev", "next", + "create", "play", "prev", "next", ["travel", "deep", "wide"], ["direct", "vertical", "horizon"], [html.HEIGHT, 100, 120, 140, 200], @@ -143,30 +122,24 @@ Volcanos(chat.ONACTION, { [html.MARGIN, 20, 40, 60], ["delay", 100, 200, 500, 1000], ], _trans: {play: "播放", prev: "上一步", next: "下一步"}, - refresh: function(event, can, button) { can.misc.localStorage(can, "web.flows.action."+button, can.Action(button)), can.onimport._flows(can, can._content_plugin) }, + refresh: function(event, can, button) { can.misc.localStorage(can, "web.flows.action."+button, can.Action(button)), can.onimport._flows(can, can.db._content_plugin) }, travel: function() {}, delay: function() {}, play: function(event, can) { var list = can.onexport.travel(can, can.db.root, true) - can.core.List(list, function(item) { - item._line && item._line.Value(html.CLASS, "") - item._rect.Value(html.CLASS, "") - item._text.Value(html.CLASS, "") - }) + can.core.List(list, function(item) { item._line && item._line.Value(html.CLASS, ""), item._rect.Value(html.CLASS, ""), item._text.Value(html.CLASS, "") }) can.core.Next(list, function(item, next, index, list) { - item._line && item._line.Value(html.CLASS, "done") - item._rect.Value(html.CLASS, "done") - item._text.Value(html.CLASS, "done") + item._line && item._line.Value(html.CLASS, "done"), item._rect.Value(html.CLASS, "done"), item._text.Value(html.CLASS, "done") can.user.toast(can, list[index].index), can.ondetail._select(event, can, item), can.onmotion.delay(can, next, 1000) }, function() { can.user.toastSuccess(can) }) }, prev: function(event, can) { var list = can.onexport.travel(can, can.db.root, true), prev - if (!can.ui.current) { can.ui.current = list.pop() } else { - can.core.List(list, function(item, index) { if (item == can.ui.current) { prev = list[index-1] } }), can.ui.current = prev - } can.ondetail._select(event, can, can.ui.current) + if (!can.db.current) { can.db.current = list.pop() } else { + can.core.List(list, function(item, index) { if (item == can.db.current) { prev = list[index-1] } }), can.db.current = prev + } can.ondetail._select(event, can, can.db.current) }, next: function(event, can) { - if (!can.ui.current) { can.ui.current = can.db.root } else { var next, list = can.onexport.travel(can, can.db.root, true) - can.core.List(list, function(item, index) { if (item == can.ui.current) { next = list[index+1] } }), can.ui.current = next - } can.ondetail._select(event, can, can.ui.current) + if (!can.db.current) { can.db.current = can.db.root } else { var next, list = can.onexport.travel(can, can.db.root, true) + can.core.List(list, function(item, index) { if (item == can.db.current) { next = list[index+1] } }), can.db.current = next + } can.ondetail._select(event, can, can.db.current) }, show: function(event, can) { can.onmotion.toggle(can, can.ui.profile), can.onimport.layout(can) }, exec: function(event, can) { can.onmotion.toggle(can, can.ui.display), can.onimport.layout(can) }, @@ -209,13 +182,13 @@ Volcanos(chat.ONKEYMAP, { r: shy("展示", function(event, can) { can.onaction.exec(event, can) }), " ": shy("展示", function(event, can) { can.onaction.exec(event, can) }), Enter: shy("预览", function(event, can) { can.onaction.show(event, can) }), - k: shy("上一步", function(event, can) { can.ui.current && can.ui.current.from? can.ondetail._select(event, can, can.ui.current.from): can.onaction.prev(event, can) }), - h: shy("前一步", function(event, can) { can.ui.current && can.ui.current.prev? can.ondetail._select(event, can, can.ui.current.prev): can.onaction.prev(event, can) }), - l: shy("后一步", function(event, can) { can.ui.current && can.ui.current.next? can.ondetail._select(event, can, can.ui.current.next): can.onaction.next(event, can) }), - j: shy("下一步", function(event, can) { can.ui.current && can.ui.current.to? can.ondetail._select(event, can, can.ui.current.to): can.onaction.next(event, can) }), - ArrowUp: shy("上一步", function(event, can) { can.ui.current && can.ui.current.from? can.ondetail._select(event, can, can.ui.current.from): can.onaction.prev(event, can) }), - ArrowLeft: shy("前一步", function(event, can) { can.ui.current && can.ui.current.prev? can.ondetail._select(event, can, can.ui.current.prev): can.onaction.prev(event, can) }), - ArrowRight: shy("后一步", function(event, can) { can.ui.current && can.ui.current.next? can.ondetail._select(event, can, can.ui.current.next): can.onaction.next(event, can) }), - ArrowDown: shy("下一步", function(event, can) { can.ui.current && can.ui.current.to? can.ondetail._select(event, can, can.ui.current.to): can.onaction.next(event, can) }), + k: shy("上一步", function(event, can) { can.db.current && can.db.current.from? can.ondetail._select(event, can, can.db.current.from): can.onaction.prev(event, can) }), + h: shy("前一步", function(event, can) { can.db.current && can.db.current.prev? can.ondetail._select(event, can, can.db.current.prev): can.onaction.prev(event, can) }), + l: shy("后一步", function(event, can) { can.db.current && can.db.current.next? can.ondetail._select(event, can, can.db.current.next): can.onaction.next(event, can) }), + j: shy("下一步", function(event, can) { can.db.current && can.db.current.to? can.ondetail._select(event, can, can.db.current.to): can.onaction.next(event, can) }), + ArrowUp: shy("上一步", function(event, can) { can.db.current && can.db.current.from? can.ondetail._select(event, can, can.db.current.from): can.onaction.prev(event, can) }), + ArrowLeft: shy("前一步", function(event, can) { can.db.current && can.db.current.prev? can.ondetail._select(event, can, can.db.current.prev): can.onaction.prev(event, can) }), + ArrowRight: shy("后一步", function(event, can) { can.db.current && can.db.current.next? can.ondetail._select(event, can, can.db.current.next): can.onaction.next(event, can) }), + ArrowDown: shy("下一步", function(event, can) { can.db.current && can.db.current.to? can.ondetail._select(event, can, can.db.current.to): can.onaction.next(event, can) }), }}, _engine: {}, }) diff --git a/core/chat/macos/desktop.css b/core/chat/macos/desktop.css index 89a6a4f3..55ce6bb6 100644 --- a/core/chat/macos/desktop.css +++ b/core/chat/macos/desktop.css @@ -1,3 +1,4 @@ +body { --desktop-icon-size:80px; } fieldset.macos.desktop { background-size:cover; background-position:center; } fieldset.macos.desktop>div.output { overflow:hidden; } fieldset.macos.desktop>div.output>fieldset.macos { background-color:transparent; } @@ -20,8 +21,8 @@ fieldset.macos.desktop>div.output>div.desktop { padding-top:25px; } fieldset.macos.desktop>div.output>div.desktop:not(.select) { display:none; } fieldset.macos.desktop>div.output>div.desktop>div.item { position:absolute; text-align:center; } fieldset.macos.desktop>div.output>div.desktop>div.item:hover { background-color:unset; } -fieldset.macos.desktop>div.output>div.desktop>div.item img { width:80px; border-radius:80px; } -fieldset.macos.desktop>div.output>div.desktop>div.item>div.name { font-size:12px; width:80px; overflow:hidden; } +fieldset.macos.desktop>div.output>div.desktop>div.item img { width:var(--desktop-icon-size); height:var(--desktop-icon-size); border-radius:var(--desktop-icon-size); object-fit:contain; } +fieldset.macos.desktop>div.output>div.desktop>div.item>div.name { font-size:12px; width:var(--desktop-icon-size); overflow:hidden; } fieldset.macos.desktop>div.output>div.desktop>fieldset { border-radius:10px; position:absolute; } fieldset.macos.desktop>div.output>div.desktop>fieldset input:not([type=button]) {width: 150px;} fieldset.macos.desktop>div.output>div.desktop>fieldset>div.output>table.content { width:100%; } @@ -53,14 +54,14 @@ fieldset.macos.menu>div.output>div.item.avatar>img { height:25px; } fieldset.macos.menu>div.output>div.menu { float:left; padding:0 20px; cursor:pointer; } fieldset.macos.menu>div.output>div.tabs { float:left; font-style:italic; padding:0 10px; } fieldset.macos.menu>div.output>div.tabs.select { background-color:transparent; color:white; } -fieldset.macos.dock>div.output { height:80px; display:flex; overflow:auto; } +fieldset.macos.dock>div.output { height:var(--desktop-icon-size); display:flex; overflow:auto; } fieldset.macos.dock>div.output>div.space { background-color:#ececec36; margin:10px; height:calc(100% - 20px); width:2px; } fieldset.macos.dock>div.output>div.item { text-align:center; align-self:baseline; transition:margin-top 0.3s; } fieldset.macos.dock>div.output>div.item>div.name { display:none; } -fieldset.macos.dock>div.output>div.item img { border-radius:80px; width:80px; transition:width 0.3s; } +fieldset.macos.dock>div.output>div.item img { border-radius:var(--desktop-icon-size); width:var(--desktop-icon-size); min-height:var(--desktop-icon-size); transition:width 0.3s; object-fit:contain; } fieldset.macos.finder>div.output>div.project>div.item input { width:100%; } fieldset.macos.finder>div.output div.content>div.item { float:left; text-align:center; } -fieldset.macos.finder>div.output div.content>div.item img { width:80px; border-radius:80px; } +fieldset.macos.finder>div.output div.content>div.item img { width:var(--desktop-icon-size); height:var(--desktop-icon-size); border-radius:var(--desktop-icon-size); object-fit:contain; } fieldset.macos.finder>div.output div.content>div.item div.name { font-size:12px; text-align:center; } div.carte.macos.float { font-size:14px; padding:10px; border:#ffffff5e solid 1px; border-radius:8px; } div.carte.macos.float div.item { background:transparent; } diff --git a/core/chat/macos/dock.go b/core/chat/macos/dock.go index 6850baf3..9ebbdd2e 100644 --- a/core/chat/macos/dock.go +++ b/core/chat/macos/dock.go @@ -17,6 +17,7 @@ func init() { DockAppend(m, "Safari", web.CHAT_IFRAME) DockAppend(m, "Terminal", web.CODE_XTERM) DockAppend(m, "", web.CODE_VIMER) + DockAppend(m, "", web.CODE_COMPILE, mdb.ICON, "usr/icons/go.png") DockAppend(m, "", web.CODE_GIT_STATUS, mdb.ICON, "usr/icons/git.jpg") } }},