diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 194b2c08..7f64cc7b 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -62,8 +62,8 @@ func _runtime_init(m *ice.Message) { nfs.Exists(m, "/proc/meminfo", func(p string) { kit.For(kit.SplitLine(m.Cmdx(nfs.CAT, p)), func(p string) { switch ls := kit.Split(p, ": "); kit.Select("", ls, 0) { - case "MemTotal", "MemFree", "MemAvailable", "Buffers", "Cached": - m.Conf(RUNTIME, kit.Keys(BOOT, ls[0]), kit.FmtSize(kit.Int(ls[1])*1024)) + case "MemTotal", "MemFree", "MemAvailable": + m.Conf(RUNTIME, kit.Keys(HOST, ls[0]), kit.FmtSize(kit.Int(ls[1])*1024)) } }) }) @@ -180,7 +180,7 @@ const RUNTIME = "runtime" func init() { Index.MergeCommands(ice.Commands{ - RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain auto upgrade reboot stash logs conf lock", Icon: "Infomation.png", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{ + RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain auto upgrade reboot stash lock", Icon: "Infomation.png", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m); aaa.White(m, ice.LICENSE) }}, IFCONFIG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(tcp.HOST) }}, DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }}, @@ -250,12 +250,6 @@ func init() { m.Cmd(SYSTEM, "git", "checkout", ".") m.Go(func() { m.Sleep30ms(ice.QUIT, 1) }) }}, - "logs": {Help: "日志", Hand: func(m *ice.Message, arg ...string) { - OpenCmds(m, kit.Format("cd %s", kit.Path("")), "tail -f var/log/bench.log") - }}, - "conf": {Help: "配置", Hand: func(m *ice.Message, arg ...string) { - OpenCmds(m, kit.Format("cd %s", kit.Path("")), "vim etc/init.shy") - }}, "lock": {Help: "锁屏", Icon: "bi bi-file-lock", Hand: func(m *ice.Message, arg ...string) { switch runtime.GOOS { case DARWIN: @@ -282,7 +276,6 @@ func ParseMake(str string) []string { res := kit.UnMarshal(str) data := kit.Value(res, MAKE) return kit.Simple( - // mdb.TIME, kit.Format(kit.Value(res, kit.Keys(BOOT, mdb.TIME))), mdb.TIME, kit.Format(kit.Value(data, mdb.TIME)), ice.SPACE, kit.Format(kit.Value(res, kit.Keys(NODE, mdb.NAME))), nfs.MODULE, kit.Format(kit.Value(data, nfs.MODULE)), diff --git a/base/cli/system.go b/base/cli/system.go index 1a77d521..616d23ff 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -130,6 +130,7 @@ const ( TIME_30ms = "30ms" TIME_30s = "30s" TIME_3s = "3s" + TIME_1s = "1s" CMD_DIR = "cmd_dir" CMD_ENV = "cmd_env" diff --git a/base/log/debug.go b/base/log/debug.go index 59246ccc..13aa1da3 100644 --- a/base/log/debug.go +++ b/base/log/debug.go @@ -6,6 +6,7 @@ import ( "unicode" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" @@ -22,11 +23,14 @@ func init() { LEVEL = "level" ) Index.MergeCommands(ice.Commands{ - DEBUG: {Name: "debug level=error,bench,debug,error,watch offset limit filter auto reset doc", Help: "后台日志", Actions: ice.Actions{ + DEBUG: {Name: "debug level=error,bench,debug,error,watch offset limit filter auto reset app doc", Help: "后台日志", Actions: ice.Actions{ "doc": {Help: "文档", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen("https://pkg.go.dev/std") }}, "reset": {Help: "重置", Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.CAT, _debug_file(arg[0]), func(line string, index int) { m.ProcessRewrite(mdb.OFFSET, index+2, mdb.LIMIT, 1000) }) }}, + "app": {Hand: func(m *ice.Message, arg ...string) { + cli.OpenCmds(m, kit.Format("cd %s", kit.Path("")), "tail -f var/log/bench.log") + }}, }, Hand: func(m *ice.Message, arg ...string) { offset, limit, stats := kit.Int(kit.Select("0", arg, 1)), kit.Int(kit.Select("1000", arg, 2)), map[string]int{} switch arg[0] { diff --git a/base/web/count.go b/base/web/count.go index c1a72e45..61b4a946 100644 --- a/base/web/count.go +++ b/base/web/count.go @@ -48,7 +48,7 @@ const COUNT = "count" func init() { Index.MergeCommands(ice.Commands{ - COUNT: &ice.Command{Name: "count hash auto group valid location", Help: "计数", Meta: kit.Dict( + COUNT: &ice.Command{Name: "count hash auto group valid location", Help: "计数器", Meta: kit.Dict( ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict(aaa.LOCATION, "地理位置")), ), Actions: ice.MergeActions(ice.Actions{ mdb.CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) { diff --git a/base/web/dream.go b/base/web/dream.go index 308fb4f7..18708a2e 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -161,8 +161,7 @@ func _dream_binary(m *ice.Message, p string) { GoToast(m, DOWNLOAD, func(toast func(string, int, int)) (list []string) { begin := time.Now() SpideSave(m, bin, kit.MergeURL(p, cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH), func(count, total, value int) { - cost := time.Now().Sub(begin) - toast(kit.FormatShow(nfs.FROM, begin.Format(ice.MOD_TIME_ONLY), cli.COST, kit.FmtDuration(cost), cli.REST, kit.FmtDuration(cost*time.Duration(101)/time.Duration(value+1)-cost)), count, total) + toast(m.Option(mdb.NAME)+" "+kit.FormatShow(cli.COST, kit.FmtDuration(time.Now().Sub(begin))), count, total) }) return nil }) diff --git a/base/web/matrix.css b/base/web/matrix.css index e249f923..365842a9 100644 --- a/base/web/matrix.css +++ b/base/web/matrix.css @@ -1,29 +1,25 @@ -fieldset.web.matrix>div.output>table.content thead { z-index:2; } -fieldset.web.matrix>div.output>table.content th { font-family:unset; padding:var(--table-padding); } -fieldset.web.matrix>div.output>table.content th i { padding:var(--input-padding); position:unset; display:unset; } +fieldset.web.matrix>div.output>table.content th { padding:var(--input-padding); } +fieldset.web.matrix>div.output>table.content th i { padding:var(--input-padding); } fieldset.web.matrix>div.output>table.content th i:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); } +fieldset.web.matrix>div.output>table.content td { padding:var(--input-padding); } fieldset.web.matrix>div.output>table.content td:hover { color:unset; } fieldset.web.matrix>div.output>table.content div.item { display:flex; align-items:center; cursor:default; } +fieldset.web.matrix>div.output>table.content div.item img { height:var(--header-height); width:var(--header-height); margin:var(--input-margin); cursor:pointer; } +fieldset.web.matrix>div.output>table.content div.item div.title { text-align:left; padding:var(--input-padding); } +fieldset.web.matrix>div.output>table.content div.item div.title>span { cursor:pointer; } +fieldset.web.matrix>div.output>table.content div.item div.status i { font-size:var(--status-font-size); padding:0; } +fieldset.web.matrix>div.output>table.content div.item div.action { margin-top:var(--input-margin); overflow:hidden; } +fieldset.web.matrix>div.output>table.content div.item div.action input.icons { display:none; } fieldset.web.matrix>div.output>table.content div.item:hover { background-color:unset; color:unset; } -fieldset.web.matrix>div.output>table.content div.item img { height:var(--header-height); width:var(--header-height); margin:var(--input-margin); } -/* fieldset.web.matrix>div.output>table.content div.item img { height:64px; width:64px; margin-right:var(--input-margin); } */ -fieldset.web.matrix>div.output>table.content div.item div.title { text-align:left; } fieldset.web.matrix>div.output>table.content div.item div.title:hover { background-color:unset; } fieldset.web.matrix>div.output>table.content div.item div.title span:hover { background-color:var(--hover-bg-color); } -fieldset.web.matrix>div.output>table.content div.item div.status i { font-size:var(--status-font-size); padding:0; } fieldset.web.matrix>div.output>table.content div.item div.status div.item:hover { background-color:var(--hover-bg-color); } -fieldset.web.matrix>div.output>table.content div.item div.action { overflow:hidden; } -fieldset.web.matrix>div.output>table.content div.item div.action input.icons { display:none; } +fieldset.web.matrix>div.output>table.content div.item.stop div.title>span { color:var(--disable-fg-color); } fieldset.web.matrix>div.output>table.content div.item.notice { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } fieldset.web.matrix>div.output>table.content div.item.danger { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } -fieldset.web.matrix>div.output>table.content div.item.danger div.status { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } -fieldset.web.matrix>div.output>table.content div.item.danger div.status div.item { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } -fieldset.web.matrix>div.output>table.content div.item.danger div.status i { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } -fieldset.web.matrix>div.output>table.content div.item.danger div.status span { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } -// fieldset.web.matrix>div.output>table.content div.item.danger div.status i { color:var(--danger-bg-color); } -// fieldset.web.matrix>div.output>table.content div.item.danger div.status span { color:var(--danger-bg-color); } -fieldset.web.matrix>div.output>table.content tr:not(:hover) div.item div.action { visibility:hidden; } +fieldset.web.matrix>div.output>table.content div.item.danger div.status div.item { color:var(--danger-fg-color); } +fieldset.web.matrix>div.output>table.content tr:not(:hover) div.action { visibility:hidden; } +body:not(.mobile) fieldset.web.matrix>div.output>table.content thead { z-index:2; } body:not(.mobile) fieldset.web.matrix>div.output>table.content th:first-child { position:sticky; left:2px; z-index:2; } body:not(.mobile) fieldset.web.matrix>div.output>table.content td:first-child { background-color:var(--plugin-bg-color); position:sticky; left:2px; z-index:1; } body:not(.mobile) fieldset.web.matrix>div.output>table.content tr.danger td:first-child { background-color:transparent; } - diff --git a/base/web/matrix.go b/base/web/matrix.go index e20a40cd..2613e5e9 100644 --- a/base/web/matrix.go +++ b/base/web/matrix.go @@ -8,21 +8,25 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" ) -func _matrix_list(m *ice.Message, domain string) (server []string) { - fields := kit.Split(mdb.Config(m, mdb.FIELD)) - button := []ice.Any{PORTAL, ADMIN, DESKTOP, kit.Select(UPGRADE, COMPILE, domain == ""), WORD, STATUS, VIMER, XTERM, cli.RUNTIME, OPEN} +func _matrix_list(m *ice.Message, domain string, fields ...string) (server []string) { value := kit.Dict(cli.ParseMake(m.Cmdx(Space(m, domain), cli.RUNTIME))) - value[mdb.TYPE], value[mdb.ICONS] = SERVER, kit.Select(nfs.USR_ICONS_ICEBERGS, ice.SRC_MAIN_ICO, domain == "") - value[DOMAIN] = kit.Select(ice.CONTEXTS, domain) - // value[mdb.TIME] = value[cli.COMPILE_TIME] + value[DOMAIN], value[mdb.TYPE], value[mdb.ICONS] = domain, SERVER, kit.Select(nfs.USR_ICONS_ICEBERGS, ice.SRC_MAIN_ICO, domain == "") + button := []ice.Any{PORTAL, ADMIN, DESKTOP, XTERM, UPGRADE, cli.RUNTIME, WORD, STATUS, VIMER, OPEN} + if domain == "" { + button = []ice.Any{PORTAL, WORD, STATUS, VIMER, COMPILE, cli.RUNTIME, XTERM, ADMIN, DESKTOP, OPEN} + } m.PushRecord(value, fields...).PushButton(button...) - m.Cmd(Space(m, domain), DREAM, ice.Maps{"space.timeout": "3s", "dream.simple": ice.TRUE}).Table(func(value ice.Maps) { + button = append(button, cli.STOP) + m.Cmd(Space(m, domain), DREAM).Table(func(value ice.Maps) { switch value[mdb.TYPE] { case WORKER: - value[DOMAIN] = kit.Select(ice.CONTEXTS, domain) + value[DOMAIN] = domain + kit.If(value[mdb.STATUS] == cli.STOP, func() { value[mdb.ICONS] = nfs.USR_ICONS_ICEBERGS }) + kit.If(value[mdb.STATUS] == cli.STOP, func() { button = []ice.Any{cli.START, mdb.REMOVE} }) m.PushRecord(value, fields...).PushButton(button...) case SERVER: server = append(server, kit.Keys(domain, value[mdb.NAME])) @@ -30,10 +34,9 @@ func _matrix_list(m *ice.Message, domain string) (server []string) { }) return } -func _matrix_cmd(m *ice.Message, action string, arg ...string) { - domain := kit.Keys(kit.Select("", m.Option(DOMAIN), m.Option(DOMAIN) != ice.CONTEXTS), m.Option(mdb.NAME)) - switch action { - case PORTAL, DESKTOP, ADMIN, OPEN: +func _matrix_action(m *ice.Message, action string, arg ...string) { + switch domain := kit.Keys(m.Option(DOMAIN), m.Option(mdb.NAME)); action { + case PORTAL, ADMIN, DESKTOP, OPEN: if kit.HasPrefixList(arg, ctx.RUN) { ProcessIframe(m, "", "", arg...) } else { @@ -51,40 +54,53 @@ func _matrix_cmd(m *ice.Message, action string, arg ...string) { } } } +func _matrix_dream(m *ice.Message, action string, arg ...string) { + m.Cmd(Space(m, m.Option(DOMAIN)), DREAM, kit.Select(m.ActionKey(), action), m.OptionSimple(mdb.NAME), arg) +} const MATRIX = "matrix" func init() { Index.MergeCommands(ice.Commands{ - MATRIX: {Name: "matrix list", Help: "空间矩阵", Meta: kit.Dict(ice.CTX_TRANS, kit.Dict( - WORD, "文档", STATUS, "源码", VIMER, "编程", cli.RUNTIME, "环境", - )), Actions: ice.MergeActions(ice.Actions{ + MATRIX: {Name: "matrix refresh", Help: "矩阵", Meta: kit.Dict( + ice.CTX_ICONS, kit.Dict(STATUS, "bi bi-git"), + ice.CTX_TRANS, kit.Dict(STATUS, "源码"), + ), Actions: ice.MergeActions(ice.Actions{ + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(DREAM, mdb.INPUTS, arg) }}, + mdb.CREATE: {Name: "create name*=hi icons repos binary template", Hand: func(m *ice.Message, arg ...string) { m.Cmd(DREAM, mdb.CREATE, arg) }}, + mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { _matrix_dream(m, nfs.TRASH); _matrix_dream(m, "") }}, + cli.START: {Hand: func(m *ice.Message, arg ...string) { _matrix_dream(m, "") }}, + cli.STOP: {Hand: func(m *ice.Message, arg ...string) { _matrix_dream(m, "") }}, + UPGRADE: {Hand: func(m *ice.Message, arg ...string) { + m.Cmd(Space(m, kit.Keys(m.Option(DOMAIN), m.Option(mdb.NAME))), UPGRADE).Sleep3s() + }}, INSTALL: {Hand: func(m *ice.Message, arg ...string) { - m.Cmd(Space(m, m.Option(DOMAIN)), DREAM, ctx.ACTION, mdb.CREATE, m.OptionSimple(mdb.NAME, mdb.ICONS, nfs.REPOS), nfs.BINARY, UserHost(m)+S(m.Option(mdb.NAME))) - m.Cmd(Space(m, m.Option(DOMAIN)), DREAM, ctx.ACTION, cli.START, m.OptionSimple(mdb.NAME)) + m.OptionDefault(nfs.BINARY, UserHost(m)+S(m.Option(mdb.NAME))) + _matrix_dream(m, mdb.CREATE, kit.Simple(m.OptionSimple(mdb.ICONS, nfs.REPOS, nfs.BINARY))...) + _matrix_dream(m, cli.START) }}, }, ctx.ConfAction(mdb.FIELD, "time,domain,status,type,name,text,icons,repos,binary,module,version")), Hand: func(m *ice.Message, arg ...string) { if kit.HasPrefixList(arg, ctx.ACTION) { - _matrix_cmd(m, arg[1], arg[2:]...) + _matrix_action(m, arg[1], arg[2:]...) return } GoToast(m, "", func(toast func(name string, count, total int)) []string { - kit.For(_matrix_list(m, ""), func(domain string, index int, total int) { + fields := kit.Split(mdb.Config(m, mdb.FIELD)) + m.Options("space.timeout", "3s", "dream.simple", ice.TRUE) + kit.For(_matrix_list(m, "", fields...), func(domain string, index int, total int) { toast(domain, index, total) - _matrix_list(m, domain) + _matrix_list(m, domain, fields...) }) - return nil - }).Sort("name,domain", "str_r", "str_r").Display("") - m.RewriteAppend(func(value, key string, index int) string { - if key == mdb.ICONS && m.Appendv(DOMAIN)[index] != ice.CONTEXTS { - if strings.HasPrefix(value, "/require/") { - value = kit.MergeURL(strings.Split(value, "?")[0], ice.POD, kit.Keys( - m.Appendv(DOMAIN)[index], m.Appendv(mdb.NAME)[index], - )) + stat := map[string]int{} + m.Table(func(value ice.Maps) { stat[value[mdb.TYPE]]++; stat[value[mdb.STATUS]]++ }).StatusTimeCount(stat) + m.RewriteAppend(func(value, key string, index int) string { + if key == mdb.ICONS && strings.HasPrefix(value, nfs.REQUIRE) && m.Appendv(DOMAIN)[index] != "" { + value = kit.MergeURL(strings.Split(value, "?")[0], ice.POD, kit.Keys(m.Appendv(DOMAIN)[index], m.Appendv(mdb.NAME)[index])) } - } - return value - }) + return value + }).Sort("status,name,domain", []string{cli.START, cli.STOP, ""}, "str_r", "str_r") + return nil + }).Action(html.FILTER, mdb.CREATE).Display("") }}, }) } diff --git a/base/web/matrix.js b/base/web/matrix.js index f5f1f1f4..5457c3f3 100644 --- a/base/web/matrix.js +++ b/base/web/matrix.js @@ -1,30 +1,35 @@ Volcanos(chat.ONIMPORT, { - _init: function(can, msg) { var list = {}, domain = {contexts: true} - msg.Table(function(value) { var name = value.name||ice.CONTEXTS; domain[value.domain] = true, list[name] = list[name]||{}, list[name][value.domain] = value }) - var ui = can.page.Append(can, can._output, [{view: [wiki.CONTENT, html.TABLE], list: [{type: html.THEAD, list: [{type: html.TR, list: can.core.Item(domain, function(domain) { - var item = list[ice.CONTEXTS][domain] - return {type: html.TH, list: [{view: [html.ITEM], list: [{img: can.misc.Resource(can, item.icons||nfs.USR_ICONS_ICEBERGS)}, - {view: wiki.TITLE, list: [{text: item.domain}, can.onappend.label(can, item, {version: icon.version, time: icon.compile}), can.onappend.buttons(can, item)]}, - ]}]} - }) }]}, {type: html.TBODY}] }]) - can.core.Item(list, function(name, value) { var i = 0; if (name == ice.CONTEXTS) { return } - var tr = can.page.Append(can, ui.tbody, [{type: html.TR, list: can.core.Item(domain, function(domain) { i++ - var item = value[domain]||{} - return {type: html.TD, list: [{view: [[html.ITEM, - !list[name][ice.CONTEXTS]? html.NOTICE: list[name][domain] && (can.core.Value(list, can.core.Keys(name, domain, nfs.VERSION)) != can.core.Value(list, can.core.Keys(name, ice.CONTEXTS, nfs.VERSION)) - || can.core.Value(list, can.core.Keys(name, domain, mdb.TIME)) < can.core.Value(list, can.core.Keys(name, ice.CONTEXTS, mdb.TIME))) - ? html.DANGER: ""]], list: item.name? [ - {img: can.misc.Resource(can, item.icons||nfs.USR_ICONS_VOLCANOS)}, - {view: wiki.TITLE, list: [{text: item.name}, can.onappend.label(can, item, {version: icon.version, time: icon.compile, time: icon.compile}), can.onappend.buttons(can, item)]}, - ]: [ - {view: html.ACTION, _init: function(target) { var worker = list[name][ice.CONTEXTS], server = list[ice.CONTEXTS][domain] - worker && can.onappend.input(can, {type: html.BUTTON, name: code.INSTALL, onclick: function(event) { - can.Update(can.request(event, {name: name, domain: domain, port: server.port}, worker), [ctx.ACTION, code.INSTALL]) - }}, "", target) - }}, - ]}]} - }) }])._target - // ; list[name][ice.CONTEXTS] || can.onappend.style(can, html.NOTICE, tr) - }), can.onmotion.delay(can, function() { can.Status(mdb.COUNT, can.core.Item(list).length+"x"+can.core.Item(domain).length) }) + _init: function(can, msg) { var list = {}, domain = {"": true} + msg.Table(function(value) { var name = value.name||"", _domain = value.domain||""; domain[_domain] = true, list[name] = list[name]||{}, list[name][_domain] = value }) + can.ui = can.page.Appends(can, can._output, [{view: [wiki.CONTENT, html.TABLE], list: [ + {type: html.THEAD, list: [{type: html.TR, list: can.core.Item(domain, function(domain) { + return {type: html.TH, list: [can.onimport.item(can, list[""][domain], list)]} + }) }]}, + {type: html.TBODY, list: can.core.Item(list, function(name, value) { if (!name) { return } + return {type: html.TR, list: can.core.Item(domain, function(domain) { var item = value[domain] + return {type: html.TD, list: [item? can.onimport.item(can, item, list): can.onimport.void(can, name, domain, list)]} + })} + })}, + ] }]), can.onmotion.delay(can, function() { can.Status(mdb.COUNT, can.core.Item(list).length+"x"+can.core.Item(domain).length) }) + }, + void: function(can, name, domain, list) { + return {view: html.ACTION, _init: function(target) { var worker = list[name][""], server = list[""][domain] + worker && can.onappend.input(can, {type: html.BUTTON, name: code.INSTALL, onclick: function(event) { + can.Update(can.request(event, {name: name, domain: domain, port: server.port}, worker), [ctx.ACTION, code.INSTALL]) + }}, "", target) + }} + }, + item: function(can, item, list) { + function cb(action) { return function(event) { can.Update(can.request(event, item), [ctx.ACTION, action]) } } + return {view: [[html.ITEM, item.type, item.status, can.onimport.style(can, item, list)]], list: [ + {img: can.misc.Resource(can, item.icons, item.domain), onclick: cb(web.DESKTOP)}, {view: wiki.TITLE, list: [ + {text: item.name||item.domain||location.host, onclick: cb(web.OPEN)}, + item.status != cli.STOP && can.onappend.label(can, item, {version: icon.version, time: icon.compile}), + can.onappend.buttons(can, item), + ]}, + ]} + }, + style: function(can, item, list) { var name = item.name||"", domain = item.domain||"", worker = list[name][""] + return !worker? html.NOTICE: (worker.status != cli.STOP && item.status != cli.STOP && (item.version != worker.version || item.time < worker.time))? html.DANGER: "" }, }, [""]) diff --git a/base/web/option.go b/base/web/option.go index d9a51ef1..1ef20052 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -151,7 +151,7 @@ func GoToast(m *ice.Message, title string, cb func(toast func(name string, count toast(kit.JoinWord(list...), len(list), _total) } else { icon = Icons[ice.SUCCESS] - m.Option(ice.TOAST_DURATION, cli.TIME_3s) + m.Option(ice.TOAST_DURATION, cli.TIME_1s) toast(ice.SUCCESS, _total, _total) } m.Sleep(m.Option(ice.TOAST_DURATION)) diff --git a/base/web/space.go b/base/web/space.go index 7df2353b..3d4a89dc 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -220,7 +220,7 @@ func _space_send(m *ice.Message, name string, arg ...string) (h string) { m.WarnNotFound(kit.IndexOf([]string{ice.OPS, ice.DEV}, target[0]) == -1, SPACE, name) }) } else if withecho { - m.Warn(!wait(), "time out") + m.Warn(!wait(), kit.Format("space %v %v time out", name, arg)) } return } diff --git a/base/web/spide.go b/base/web/spide.go index ffbcd54d..f35ec833 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -468,7 +468,7 @@ func SpideCache(m *ice.Message, link string) *ice.Message { func SpideOrigin(m *ice.Message, name string) string { return m.Cmdv(SPIDE, name, CLIENT_ORIGIN) } func SpideURL(m *ice.Message, name string) string { return m.Cmdv(SPIDE, name, CLIENT_URL) } func ProcessIframe(m *ice.Message, title, link string, arg ...string) *ice.Message { - if m.IsMetaKey() || m.IsMobileUA() { + if m.IsMetaKey() { m.ProcessOpen(link) return m } diff --git a/base/web/store.go b/base/web/store.go index 6ef53966..556a889f 100644 --- a/base/web/store.go +++ b/base/web/store.go @@ -18,7 +18,7 @@ const STORE = "store" func init() { Index.MergeCommands(ice.Commands{ - STORE: {Name: "store refresh", Help: "空间商店", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{ + STORE: {Name: "store refresh", Help: "商店", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{ mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPIDE, mdb.INPUTS, arg) }}, mdb.CREATE: {Name: "create name* origin* icons", Hand: func(m *ice.Message, arg ...string) { m.Cmd(SPIDE, mdb.CREATE, m.OptionSimple("name,origin,icons"), mdb.TYPE, nfs.REPOS) @@ -73,11 +73,11 @@ func init() { m.Push("", value, kit.Split("time,name,icons,repos,binary,module,version")) m.Push(mdb.TEXT, value[nfs.REPOS]).Push(ORIGIN, origin) if _, ok := list[value[mdb.NAME]]; ok || arg[0] == ice.OPS { - m.PushButton(OPEN, PORTAL) + m.PushButton(PORTAL, OPEN) } else if ice.Info.NodeType == WORKER || !aaa.IsTechOrRoot(m) { m.PushButton(PORTAL) } else { - m.PushButton(INSTALL, PORTAL) + m.PushButton(PORTAL, INSTALL) } }) m.StatusTimeCount(ORIGIN, origin) diff --git a/core/chat/macos/menu.js b/core/chat/macos/menu.js index d72bea6e..6e3fcf5b 100644 --- a/core/chat/macos/menu.js +++ b/core/chat/macos/menu.js @@ -6,7 +6,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.page.style(can, can._ou ].concat(msg.Table(function(item) { return {view: [html.ITEM], list: [{img: can.page.drawText(can, item.name||item.index, 25, 0, 20)}], onclick: function(event) { can.sup.onexport.record(can, item) }} }), [ - {view: [[html.MENU, "title"]], list: [{img: can.misc.ResourceFavicon(can)}, {text: can.ConfSpace()||can.misc.Search(can, ice.POD)||location.host}], + {view: [[html.MENU, "title"]], list: [{img: can.misc.ResourceFavicon(can)}, {text: decodeURIComponent(can.ConfSpace()||can.misc.Search(can, ice.POD)||location.host)}], onclick: function(event) { can.sup.onexport.record(can, html.DESKTOP) }}, {view: [[html.MENU, mdb.ICON, web.REFRESH], "", can.page.unicode.refresh], onclick: function(event) { can.user.reload(true) }}, {view: [[html.MENU, mdb.ICON, mdb.CREATE], "", can.page.unicode.create], onclick: function(event) { can.sup.onexport.record(can, mdb.CREATE) }}, diff --git a/core/code/upgrade.go b/core/code/upgrade.go index 2c0c722c..c255668d 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -42,13 +42,9 @@ func init() { m.Option(ice.EXIT, ice.TRUE) } uri := "/publish/" + kit.Format(value[nfs.FILE]) - m.Debug("what %v", uri) - m.Debug("what %v", ice.Info.Make.Domain) kit.If(m.Spawn().Options(ice.MSG_USERPOD, "").ParseLink(ice.Info.Make.Domain).Option(ice.MSG_USERPOD), func(p string) { - m.Debug("what %v", p) uri = kit.MergeURL(uri, ice.POD, p) }) - m.Debug("what %v", uri) dir := path.Join(kit.Format(value[nfs.PATH]), kit.Format(value[nfs.FILE])) web.GoToast(m, web.DOWNLOAD, func(toast func(name string, count, total int)) []string { switch web.SpideSave(m, dir, uri, func(count, total, value int) { @@ -65,8 +61,7 @@ func init() { m.Cmdy(nfs.DIR, dir, "time,size,path,hash").Push(web.ORIGIN, kit.MergeURL2(web.SpideOrigin(m, ice.DEV_IP), uri)) }) if web.ToastSuccess(m); m.Option(ice.EXIT) == ice.TRUE { - web.Toast(m, cli.RESTART) - m.Cmd("", cli.RESTART) + web.Toast(m, cli.RESTART).Cmd("", cli.RESTART) } }}, }}) diff --git a/render.go b/render.go index 79bb2a40..f3aa17ce 100644 --- a/render.go +++ b/render.go @@ -31,6 +31,9 @@ func Render(m *Message, cmd string, args ...Any) string { case []string: kit.For(k, func(k string) { list = append(list, Render(m, RENDER_BUTTON, k)) }) case string: + if k == "" { + break + } if strings.HasPrefix(k, "