From b31c63989f9c5a48c5725d95e99432aa413938fa Mon Sep 17 00:00:00 2001 From: shy Date: Tue, 27 Feb 2024 00:58:58 +0800 Subject: [PATCH] add web.group --- base/web/matrix.go | 63 ++++++++++++++++++++++++++----------- base/web/matrix.js | 19 ++++++----- base/web/render.go | 1 + base/web/space.go | 6 ++-- base/web/toast.go | 2 +- conf.go | 1 + core/chat/chat.go | 8 ++++- core/chat/group.go | 33 +++++++++++++++++++ core/chat/header.go | 5 ++- core/chat/macos/desktop.css | 4 +-- core/chat/message.go | 18 ++++++----- core/chat/message.js | 26 +++++++-------- misc/git/repos.go | 11 +++---- 13 files changed, 132 insertions(+), 65 deletions(-) create mode 100644 core/chat/group.go diff --git a/base/web/matrix.go b/base/web/matrix.go index 9b69aa12..f5506880 100644 --- a/base/web/matrix.go +++ b/base/web/matrix.go @@ -14,17 +14,26 @@ import ( kit "shylinux.com/x/toolkits" ) -func _matrix_list(m *ice.Message, domain, icon string, fields ...string) (server, icons []string) { +func _matrix_list(m *ice.Message, domain, icon, typ string, fields ...string) (server, icons, types []string) { value := kit.Dict(cli.ParseMake(m.Cmdx(Space(m, domain), cli.RUNTIME))) - value[DOMAIN], value[mdb.TYPE], value[mdb.ICONS] = domain, SERVER, icon - button := []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, UPGRADE, cli.RUNTIME, DREAM, WORD, STATUS, VIMER, XTERM} - if domain == "" { - button = []ice.Any{PORTAL, WORD, STATUS, VIMER, COMPILE, cli.RUNTIME, XTERM, DESKTOP, DREAM, ADMIN, OPEN} + value[DOMAIN], value[mdb.ICONS], value[mdb.TYPE] = domain, icon, typ + button := []ice.Any{} + switch typ { + case MYSELF: + button = []ice.Any{PORTAL, WORD, STATUS, VIMER, COMPILE, cli.RUNTIME, DREAM, XTERM, DESKTOP, ADMIN, OPEN} + case SERVER: + button = []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, UPGRADE, cli.RUNTIME, DREAM, WORD, STATUS, VIMER, XTERM} + default: + button = []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, XTERM, cli.RUNTIME, DREAM, WORD, STATUS, VIMER} } m.PushRecord(value, fields...).PushButton(button...) - button = []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, UPGRADE, cli.RUNTIME, WORD, STATUS, VIMER, XTERM} - if domain == "" { + switch typ { + case MYSELF: button = []ice.Any{PORTAL, WORD, STATUS, VIMER, COMPILE, cli.RUNTIME, XTERM, DESKTOP, ADMIN, OPEN} + case SERVER: + button = []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, UPGRADE, cli.RUNTIME, WORD, STATUS, VIMER, XTERM} + default: + button = []ice.Any{PORTAL, DESKTOP, ADMIN, OPEN, XTERM, cli.RUNTIME, WORD, STATUS, VIMER} } button = append(button, cli.STOP) m.Cmd(Space(m, domain), DREAM).Table(func(value ice.Maps) { @@ -37,6 +46,7 @@ func _matrix_list(m *ice.Message, domain, icon string, fields ...string) (server case SERVER, MASTER: server = append(server, kit.Keys(domain, value[mdb.NAME])) icons = append(icons, value[mdb.ICONS]) + types = append(types, value[mdb.TYPE]) } }) return @@ -47,11 +57,24 @@ func _matrix_action(m *ice.Message, action string, arg ...string) { if kit.HasPrefixList(arg, ctx.RUN) { ProcessIframe(m, "", "", arg...) } else { - title, link := kit.Keys(domain, kit.Select("", action, action != OPEN)), kit.Select("", S(domain), domain != "")+kit.Select("", C(action), action != OPEN) - ProcessIframe(m, kit.Select(ice.CONTEXTS, title), kit.Select(nfs.PS, link), arg...).ProcessField(ctx.ACTION, action, ctx.RUN) + title, link := kit.Keys(domain, action), kit.Select("", S(domain), domain != "")+C(action) + if m.Option(mdb.TYPE) == MASTER { + link = kit.MergeURL2(SpideOrigin(m, m.Option(DOMAIN)), C(action)) + if kit.IsIn(action, ADMIN) { + m.ProcessOpen(link) + break + } + } + ProcessIframe(m, title, kit.Select(nfs.PS, link), arg...).ProcessField(ctx.ACTION, action, ctx.RUN) } case OPEN: - m.ProcessOpen(kit.Select(nfs.PS, S(domain), domain != "")) + link := kit.Select(nfs.PS, S(domain), domain != "") + if m.Option(mdb.TYPE) == MASTER { + link = SpideOrigin(m, m.Option(DOMAIN)) + } else if m.Option("server.type") == MASTER { + link = kit.MergeURL2(SpideOrigin(m, m.Option(DOMAIN)), S(m.Option(mdb.NAME))) + } + m.ProcessOpen(link) default: if !kit.HasPrefixList(arg, ctx.RUN) { kit.If(action == XTERM, func() { arg = []string{cli.SH} }) @@ -71,8 +94,10 @@ const MATRIX = "matrix" func init() { Index.MergeCommands(ice.Commands{ - MATRIX: {Name: "matrix refresh", Help: "矩阵", Meta: kit.Dict( - ice.CTX_ICONS, kit.Dict(STATUS, "bi bi-git"), ice.CTX_TRANS, kit.Dict(STATUS, "源码"), + MATRIX: {Name: "matrix refresh", Help: "矩阵", Icon: "Mission Control.png", Meta: kit.Dict( + ice.CTX_ICONS, kit.Dict(STATUS, "bi bi-git"), ice.CTX_TRANS, kit.Dict( + STATUS, "源码", html.INPUT, kit.Dict(MYSELF, "本机", MASTER, "主机"), + ), ), 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) }}, @@ -82,7 +107,7 @@ func init() { COMPILE: {Hand: func(m *ice.Message, arg ...string) { _matrix_cmd(m, "", cli.AMD64, cli.LINUX, ice.SRC_MAIN_GO).ProcessHold() }}, - UPGRADE: {Hand: func(m *ice.Message, arg ...string) { _matrix_cmd(m, "").ProcessRefresh().Sleep3s() }}, + UPGRADE: {Hand: func(m *ice.Message, arg ...string) { _matrix_cmd(m, "").Sleep3s().ProcessRefresh() }}, INSTALL: {Hand: func(m *ice.Message, arg ...string) { if kit.IsIn(m.Cmdv(Space(m, m.Option(DOMAIN)), SPIDE, ice.DEV_IP, CLIENT_HOSTNAME), m.Cmd(tcp.HOST).Appendv(aaa.IP)...) { m.Option(nfs.BINARY, S(m.Option(mdb.NAME))) @@ -98,11 +123,11 @@ func init() { } GoToast(m, func(toast func(name string, count, total int)) []string { field := kit.Split(mdb.Config(m, mdb.FIELD)) - m.Options("space.timeout", cli.TIME_300ms, "dream.simple", ice.TRUE) - list, icons := _matrix_list(m, "", ice.SRC_MAIN_ICO, field...) + m.Options("space.timeout", cli.TIME_1s, "dream.simple", ice.TRUE) + list, icons, types := _matrix_list(m, "", ice.SRC_MAIN_ICO, MYSELF, field...) kit.For(list, func(domain string, index int, total int) { toast(domain, index, total) - _matrix_list(m, domain, icons[index], field...) + _matrix_list(m, domain, icons[index], types[index], field...) }) m.RewriteAppend(func(value, key string, index int) string { if key == mdb.ICONS && strings.HasPrefix(value, nfs.REQUIRE) && m.Appendv(DOMAIN)[index] != "" { @@ -110,10 +135,10 @@ func init() { } return value }) - m.Sort("type,status,name,domain", []string{MASTER, SERVER, WORKER, ""}, []string{cli.START, cli.STOP, ""}, "str_r", "str") - m.StatusTimeCountStats(mdb.TYPE, mdb.STATUS) + m.Action(html.FILTER, mdb.CREATE).StatusTimeCountStats(mdb.TYPE, mdb.STATUS).Display("") + m.Sort("type,status,name,domain", []string{WORKER, MYSELF, SERVER, MASTER, ""}, []string{cli.START, cli.STOP, ""}, "str_r", "str_r") return nil - }).Action(html.FILTER, mdb.CREATE).Display("") + }) ctx.Toolkit(m) }}, }) diff --git a/base/web/matrix.js b/base/web/matrix.js index 83b62b57..04626fb6 100644 --- a/base/web/matrix.js +++ b/base/web/matrix.js @@ -1,9 +1,7 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { var list = {}, domain = [""] - msg.Table(function(value) { - var name = value.name, _domain = value.domain - domain.indexOf(_domain) == -1 && (domain.push(_domain)) - list[name] = list[name]||{}, list[name][_domain] = value + msg.Table(function(value) { var name = value.name, _domain = value.domain + list[name] = list[name]||{}, list[name][_domain] = value, domain.indexOf(_domain) == -1 && domain.push(_domain) }) can.ui = can.page.Appends(can, can._output, [{view: [wiki.CONTENT, html.TABLE], list: [ {type: html.THEAD, list: [{type: html.TR, list: can.core.List(domain, function(domain) { @@ -16,24 +14,25 @@ Volcanos(chat.ONIMPORT, { })}, ] }]), can.onmotion.delay(can, function() { can.Status(mdb.COUNT, can.core.Item(list).length+"x"+can.core.List(domain).length) }) }, - void: function(can, name, domain, list) { - return {view: html.ACTION, _init: function(target) { var worker = list[name][""], server = list[""][domain] + void: function(can, name, domain, list) { var worker = list[name][""], server = list[""][domain] + return {view: html.ACTION, _init: function(target) { 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]) + can.Update(can.request(event, {name: name, domain: domain}, worker), [ctx.ACTION, code.INSTALL]) }}, "", target) }} }, - item: function(can, item, list) { + item: function(can, item, list) { var name = item.name, domain = item.domain, worker = list[name][""], server = list[""][domain] + item["server.type"] = server.type 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: [ + {img: can.misc.Resource(can, item.icons, can.core.Keys(item.domain, item.name)), 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][""] + 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/render.go b/base/web/render.go index ddaff84b..486fd058 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -158,6 +158,7 @@ const ( XTERM = "xterm" GRANT = "grant" DESKTOP = "desktop" + MESSAGE = "message" AUTOGEN = "autogen" BINPACK = "binpack" diff --git a/base/web/space.go b/base/web/space.go index 194a0e87..e948bbca 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -185,6 +185,7 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc kit.If(m.Option(ice.MSG_DAEMON), func(p string) { m.Option(ice.MSG_DAEMON, kit.Keys(kit.Slice(kit.Reverse(kit.Simple(source)), 0, -1), p)) }) + m.Option(ice.FROM_SPACE, kit.Keys(kit.Reverse(source[1:]))) kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(true, func(_ *ice.Message) { m = m.Cmd() }) }) kit.If(m.Optionv(ice.MSG_ARGS) != nil, func() { m.Options(ice.MSG_ARGS, kit.Simple(m.Optionv(ice.MSG_ARGS))) }) } @@ -246,6 +247,7 @@ const ( PORTAL = "portal" WORKER = "worker" SERVER = "server" + MYSELF = "myself" MASTER = "master" REDIAL = "redial" @@ -398,8 +400,8 @@ func init() { m.SetAppend() case tcp.WIFI: m.Cmdy(tcp.WIFI).CutTo(tcp.SSID, arg[0]) - case "message": - m.Cmdy("web.chat.message").Cut(mdb.HASH, mdb.NAME, mdb.ICONS) + case MESSAGE: + m.Cmdy(MESSAGE).Cut(mdb.HASH, mdb.ZONE, mdb.ICONS) } }) ice.Info.AdminCmd = AdminCmd diff --git a/base/web/toast.go b/base/web/toast.go index 32474f6b..1d750059 100644 --- a/base/web/toast.go +++ b/base/web/toast.go @@ -62,7 +62,7 @@ func ToastSuccess(m *ice.Message, arg ...ice.Any) { Toast(m, toastContent(m, ice.SUCCESS, arg...), "", cli.TIME_3s) } func ToastFailure(m *ice.Message, arg ...ice.Any) { - Toast(m, toastContent(m, ice.FAILURE, arg...), "", m.OptionDefault(ice.TOAST_DURATION, "-1")).Sleep(m.OptionDefault(ice.TOAST_DURATION, cli.TIME_3s)) + Toast(m, toastContent(m, ice.FAILURE, arg...), "", m.Option(ice.TOAST_DURATION, "-1")).Sleep(cli.TIME_3s) } func ToastProcess(m *ice.Message, arg ...ice.Any) func(...ice.Any) { text := toastContent(m, ice.PROCESS, arg...) diff --git a/conf.go b/conf.go index 6cf01869..039db7a3 100644 --- a/conf.go +++ b/conf.go @@ -244,6 +244,7 @@ const ( // MSG MSG_NODETYPE = "node.type" FROM_DAEMON = "from.daemon" + FROM_SPACE = "from.space" TABLE_CHECKBOX = "table.checkbox" TOAST_DURATION = "toast.duration" ) diff --git a/core/chat/chat.go b/core/chat/chat.go index c8effaf7..d9de4f70 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -10,6 +10,12 @@ const CHAT = "chat" var Index = &ice.Context{Name: CHAT, Help: "聊天中心"} -func init() { web.Index.Register(Index, &web.Frame{}, HEADER, IFRAME, FAVOR) } +func init() { + web.Index.Register(Index, &web.Frame{}, + HEADER, FOOTER, + IFRAME, FAVOR, + MESSAGE, + ) +} func Prefix(arg ...string) string { return web.Prefix(CHAT, kit.Keys(arg)) } diff --git a/core/chat/group.go b/core/chat/group.go new file mode 100644 index 00000000..9abbef32 --- /dev/null +++ b/core/chat/group.go @@ -0,0 +1,33 @@ +package chat + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/tcp" + "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" +) + +const GROUP = "group" + +func init() { + Index.MergeCommands(ice.Commands{ + GROUP: {Help: "群组", Icon: "Contacts.png", Actions: ice.MergeActions(ice.Actions{ + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case mdb.NAME: + m.AdminCmd(web.MATRIX).Table(func(value ice.Maps) { + m.Push(arg[0], kit.Keys(kit.Select("", ice.OPS, ice.Info.NodeType == web.WORKER), value[web.DOMAIN], value[mdb.NAME])) + m.Push(mdb.TYPE, value[mdb.TYPE]) + }) + } + }}, + mdb.CREATE: {Name: "create type*=worker,server,master, name*"}, + tcp.SEND: {Name: "send text=hi", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(web.SPACE, m.Option(mdb.NAME), Prefix(MESSAGE), tcp.RECV, mdb.TEXT, m.Option(mdb.TEXT)) + }}, + }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type*,name*")), Hand: func(m *ice.Message, arg ...string) { + mdb.HashSelect(m, arg...).PushAction(tcp.SEND, mdb.REMOVE) + }}, + }) +} diff --git a/core/chat/header.go b/core/chat/header.go index 598cd1e2..6d6abda3 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -95,10 +95,9 @@ func init() { }}, MESSAGE: {Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.INPUTS || arg[0] == mdb.ACTION && arg[1] == mdb.INPUTS { - m.Cmdy(MESSAGE, arg) + m.Cmdy(web.Space(m, m.Option(ice.POD)), MESSAGE, arg) } else { - m.Cmdy(MESSAGE, mdb.INSERT, arg) - web.ToastSuccess(m) + m.Cmdy(web.Space(m, m.Option(ice.POD)), MESSAGE, mdb.INSERT, arg).ToastSuccess() } }}, aaa.LOGOUT: {Hand: aaa.SessLogout}, diff --git a/core/chat/macos/desktop.css b/core/chat/macos/desktop.css index 6be6e3b4..18d1f6fd 100644 --- a/core/chat/macos/desktop.css +++ b/core/chat/macos/desktop.css @@ -74,10 +74,10 @@ fieldset.macos.dock>div.output>div.space { background-color:#ececec36; margin:va 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 img { object-fit:contain; min-height:var(--desktop-icon-size); width:var(--desktop-icon-size); transition:width 0.3s; } fieldset.macos.dock>div.output>div.item>div.name { display:none; } -fieldset.macos.finder>div.output div.content>div.item { text-align:center; float:left; } +fieldset.macos.finder>div.output div.content>div.item { text-align:center; float:left; width:var(--desktop-icon-size); } fieldset.macos.finder>div.output div.content>div.item img { object-fit:contain; width:var(--desktop-icon-size); } fieldset.macos.finder>div.output div.content>div.item img { object-fit:contain; width:var(--desktop-icon-size); height:var(--desktop-icon-size); } -fieldset.macos.finder>div.output div.content>div.item div.name { font-size:var(--code-font-size); text-align:center; } +fieldset.macos.finder>div.output div.content>div.item div.name { font-size:var(--code-font-size); white-space:pre; text-align:center; overflow:hidden; } body.dark fieldset.macos.desktop>div.output>fieldset.macos { background-color:#08234ad1; } body.dark fieldset.macos.desktop>div.output>div.desktop fieldset table.content tbody tr:nth-child(odd):not(:hover) { background-color:#282B2F; } body.dark fieldset.macos.desktop>div.output>div.desktop fieldset table.content tbody tr:nth-child(even):not(:hover) { background-color:#1a1d1e; } diff --git a/core/chat/message.go b/core/chat/message.go index 19ed4446..eebe371a 100644 --- a/core/chat/message.go +++ b/core/chat/message.go @@ -6,6 +6,7 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -20,17 +21,18 @@ func init() { messageCreate(m, cli.SYSTEM, "usr/icons/System Settings.png") messageInsert(m, cli.SYSTEM, mdb.TYPE, "plug", ctx.INDEX, cli.RUNTIME) }}, - mdb.CREATE: {Name: "create type*=tech,void name* icons*"}, + mdb.CREATE: {Name: "create type*=tech,void zone* icons*"}, mdb.INSERT: {Hand: func(m *ice.Message, arg ...string) { - mdb.ZoneInsert(m, append(arg, aaa.AVATAR, aaa.UserInfo(m, "", aaa.AVATAR, aaa.AVATAR), - aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), - )) + mdb.ZoneInsert(m, append(arg, aaa.AVATAR, aaa.UserInfo(m, "", aaa.AVATAR, aaa.AVATAR), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME))) + }}, + tcp.RECV: {Hand: func(m *ice.Message, arg ...string) { + mdb.ZoneInsert(m, kit.Simple(mdb.ZONE, m.Option(ice.FROM_SPACE), arg, aaa.AVATAR, aaa.UserInfo(m, "", aaa.AVATAR, aaa.AVATAR), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME))) }}, web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) { messageInsert(m, web.DREAM, mdb.TYPE, "plug", ctx.INDEX, IFRAME, ctx.ARGS, web.S(m.Option(mdb.NAME))) }}, }, web.DreamAction(), mdb.ZoneAction( - mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,type,name,icons", mdb.FIELDS, "time,id,avatar,usernick,username,type,name,text,space,index,args", + mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,hash,type,zone,icons", mdb.FIELDS, "time,id,avatar,usernick,username,type,name,text,space,index,args", )), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { mdb.ZoneSelect(m.Display("").Spawn(), arg...).Table(func(value ice.Maps) { @@ -44,9 +46,9 @@ func init() { }}, }) } -func messageCreate(m *ice.Message, name, icon string) { - kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, name, mdb.META), kit.Dict( - mdb.TIME, m.Time(), mdb.TYPE, aaa.TECH, mdb.NAME, name, mdb.ICONS, icon, +func messageCreate(m *ice.Message, zone, icons string) { + kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, zone, mdb.META), kit.Dict( + mdb.TIME, m.Time(), mdb.TYPE, aaa.TECH, mdb.ZONE, zone, mdb.ICONS, icons, )) } func messageInsert(m *ice.Message, zone string, arg ...string) { diff --git a/core/chat/message.js b/core/chat/message.js index 68ce6dac..51976dd3 100644 --- a/core/chat/message.js +++ b/core/chat/message.js @@ -1,6 +1,6 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { - if (can.isCmdMode()) { can.onappend.style(can, html.OUTPUT) } + // if (can.isCmdMode()) { can.onappend.style(can, html.OUTPUT) } can.ui = can.onappend.layout(can), can.onimport._project(can, msg) }, _project: function(can, msg) { var select, current = can.db.hash[0]||ice.DEV @@ -12,27 +12,27 @@ Volcanos(chat.ONIMPORT, { msg.Table(function(value) { var _target = can.page.Append(can, can.ui.project, [{view: html.ITEM, list: [ {img: can.misc.Resource(can, value.icons||"usr/icons/Messages.png")}, {view: html.CONTAINER, list: [ - {view: wiki.TITLE, list: [{text: value.name||"[未命名]"}, {text: [can.base.TimeTrim(value.time), "", mdb.TIME]}]}, + {view: wiki.TITLE, list: [{text: value.zone||"[未命名]"}, {text: [can.base.TimeTrim(value.time), "", mdb.TIME]}]}, {view: wiki.CONTENT, list: [{text: value.text||"[未知消息]"}]}, ]}, - ], onclick: function(event) { can.isCmdMode() && can.misc.SearchHash(can, value.name), can.onimport._switch(can, false) + ], onclick: function(event) { can.isCmdMode() && can.misc.SearchHash(can, value.zone), can.onimport._switch(can, false) can.db.zone = value, can.db.hash = value.hash, can.onmotion.select(can, can.ui.project, html.DIV_ITEM, _target) if (can.onmotion.cache(can, function(save, load) { can.ui.message && save({title: can.ui.title, message: can.ui.message, scroll: can.ui.message.scrollTop}) - return load(value.name, function(bak) { can.ui.title = bak.title, can.ui.message = bak.message + return load(value.zone, function(bak) { can.ui.title = bak.title, can.ui.message = bak.message can.onmotion.delay(can, function() { can.ui.message.scrollTop = bak.scroll }) }) }, can.ui.content, can.ui.profile, can.ui.display, can._status)) { return can.onimport.layout(can) } can.run(can.request(event, {"cache.limit": 10}), [value.hash], function(msg) { can.onimport._display(can), can.onimport._content(can, msg) }) - }}])._target; select = (value.name == current? _target: select)||_target + }}])._target; select = (value.zone == current? _target: select)||_target }), can.user.isMobile? can.onimport._switch(can, true): select && select.click() }, _content: function(can, msg) { can.ui.title = can.page.Appends(can, can.ui.content, [{view: wiki.TITLE, list: [ {icon: "bi bi-chevron-left", onclick: function() { can.onimport._switch(can, true) }}, - {text: can.db.zone.name}, + {text: can.db.zone.zone}, {icon: "bi bi-three-dots", onclick: function() { can.onmotion.toggle(can, can.ui.profile), can.onimport.layout(can) }}, ]}])._target can.ui.message = can.page.Append(can, can.ui.content, [{view: html.LIST}])._target, can.onimport._message(can, msg) @@ -52,8 +52,8 @@ Volcanos(chat.ONIMPORT, { can.page.Append(can, can.ui.message, [{view: [[html.ITEM, mdb.TIME], "", time]}]) } can.page.Append(can, can.ui.message, [{view: [[html.ITEM, value.type, myself? "myself": ""]], list: [ - {img: can.misc.Resource(can, (value.avatar == can.db.zone.name? "": value.avatar)||can.db.zone.icons||"usr/icons/Messages.png")}, - {view: html.CONTAINER, list: [{text: [value.usernick, "", nfs.FROM]}, can.onfigure[value.type](can, value)]}, + {img: can.misc.Resource(can, (value.avatar == can.db.zone.zone? "": value.avatar)||can.db.zone.icons||"usr/icons/Messages.png")}, + {view: html.CONTAINER, list: [{text: [value.usernick, "", nfs.FROM]}, can.onfigure[value.type||"text"](can, value)]}, ]}]) }), can.onappend._status(can, msg.Option(ice.MSG_STATUS)), can.onimport.layout(can) if (can.Status(mdb.TOTAL) > can.db.zone.id) { can.onimport._request(can) } @@ -114,19 +114,19 @@ Volcanos(chat.ONFIGURE, { }) Volcanos(chat.ONINPUTS, { _show: function(event, can, msg, target, name) { - function show(value) { - if (target == target.parentNode.firstChild) { can.ui = can.ui||{} + function show(value) { can.ui = can.ui||{} + if (!can.ui.img) { can.ui.img = can.page.insertBefore(can, [{type: html.IMG}], target) can.ui.span = can.page.insertBefore(can, [{type: html.SPAN}], target) can.onappend.style(can, mdb.ICONS, can.page.parentNode(can, target, html.TR)) can.page.style(can, target, html.COLOR, html.TRANSPARENT) } - can.ui.img.src = can.misc.Resource(can, value.icons), can.ui.span.innerText = value.name + can.ui.img.src = can.misc.Resource(can, value.icons||"usr/icons/Messages.png"), can.ui.span.innerText = value.zone target.value = value.hash, can.onmotion.hidden(can, can._target) } can.page.Appends(can, can._output, msg.Table(function(value) { - return value.name && {view: html.ITEM, list: [ - {img: can.misc.Resource(can, value.icons)}, {text: value.name}, + return value.zone && {view: html.ITEM, list: [ + {img: can.misc.Resource(can, value.icons||"usr/icons/Messages.png")}, {text: value.zone}, ], onclick: function(event) { show(value) }} })) }, diff --git a/misc/git/repos.go b/misc/git/repos.go index fa02bee9..bc16c368 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -109,14 +109,15 @@ func _repos_open(m *ice.Message, p string) *git.Repository { return mdb.HashSelectTarget(m, p, nil).(*git.Repository) } func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps) error) { - web.GoToast(m, func(toast func(string, int, int)) []string { + web.GoToast(m, func(toast func(string, int, int)) (res []string) { m.Cmd("").Table(func(value ice.Maps, index, total int) { toast(value[REPOS], index, total) if err := cb(_repos_open(m, value[REPOS]), value); err != nil && err != git.NoErrAlreadyUpToDate { web.ToastFailure(m, value[REPOS], err.Error()) + res = append(res, value[REPOS]) } }) - return nil + return }) } func _repos_each_origin(m *ice.Message, title string, cb func(*git.Repository, string, *http.BasicAuth, ice.Maps) error) { @@ -650,15 +651,13 @@ func init() { }}, }, web.StatsAction("", "代码库总数"), web.DreamAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,message,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { - mdb.HashSelect(m, arg...).Sort(REPOS) - m.Table(func(value ice.Maps) { + mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { if strings.Contains(value[VERSION], "-") { m.PushButton(STATUS, TAG, mdb.REMOVE) } else { m.PushButton(STATUS, mdb.REMOVE) } - }) - m.Action(CLONE, PULL, PUSH, STATUS) + }).Action(CLONE, PULL, PUSH, STATUS).Sort(REPOS) } else if repos := _repos_open(m, arg[0]); len(arg) == 1 { _repos_branch(m, repos) } else if len(arg) == 2 {