diff --git a/base/ctx/command.go b/base/ctx/command.go index bc1952d5..a2584a01 100644 --- a/base/ctx/command.go +++ b/base/ctx/command.go @@ -51,6 +51,7 @@ const ( OPTS = "opts" STYLE = "style" DISPLAY = "display" + PREVIEW = "preview" ACTION = "action" TOOLS = "tools" RUN = "run" diff --git a/base/web/count.go b/base/web/count.go index a3146c70..03c60ca2 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 filter", 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 8e252b71..71ebb4ad 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -123,23 +123,12 @@ func _dream_start(m *ice.Message, name string) { if m.WarnNotValid(name == "", mdb.NAME) { return } - defer ToastProcess(m)() - defer m.ProcessOpen(m.MergePod(name)) - defer mdb.Lock(m, m.PrefixKey(), cli.START, name)() - p := path.Join(ice.USR_LOCAL_WORK, name) - if p := path.Join(p, ice.Info.PidPath); nfs.Exists(m, p) { - if pid := m.Cmdx(nfs.CAT, p, kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { - m.Info("already exists %v", pid) - return - } - for i := 0; i < 3; i++ { - if m.Cmd(SPACE, name).Length() > 0 { - m.Info("already exists %v", name) - return - } - m.Sleep300ms() - } + if !m.IsCliUA() { + defer ToastProcess(m)() + defer m.ProcessOpen(m.MergePod(name)) } + defer mdb.Lock(m, m.PrefixKey(), cli.START, name)() + p := _dream_check(m, name) defer m.Options(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "") m.Options(cli.CMD_DIR, kit.Path(p), cli.CMD_ENV, kit.EnvList(kit.Simple(m.OptionSimple(ice.TCP_DOMAIN), cli.CTX_OPS, HostPort(m, tcp.LOCALHOST, m.Cmdv(SERVE, tcp.PORT)), cli.CTX_LOG, ice.VAR_LOG_BOOT_LOG, cli.CTX_PID, ice.VAR_LOG_ICE_PID, @@ -154,6 +143,23 @@ func _dream_start(m *ice.Message, name string) { gdb.WaitEvent(m, DREAM_OPEN, func(m *ice.Message, arg ...string) bool { return m.Option(mdb.NAME) == name }) m.Sleep300ms() } +func _dream_check(m *ice.Message, name string) string { + p := path.Join(ice.USR_LOCAL_WORK, name) + if p := path.Join(p, ice.Info.PidPath); nfs.Exists(m, p) { + if pid := m.Cmdx(nfs.CAT, p, kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { + m.Info("already exists %v", pid) + return p + } + for i := 0; i < 3; i++ { + if m.Cmd(SPACE, name).Length() > 0 { + m.Info("already exists %v", name) + return p + } + m.Sleep300ms() + } + } + return p +} func _dream_binary(m *ice.Message, p string) { if bin := path.Join(m.Option(cli.CMD_DIR), ice.BIN_ICE_BIN); nfs.Exists(m, bin) { return @@ -198,11 +204,11 @@ const ( DREAM_CREATE = "dream.create" DREAM_REMOVE = "dream.remove" + DREAM_TRASH = "dream.trash" DREAM_START = "dream.start" DREAM_STOP = "dream.stop" DREAM_OPEN = "dream.open" DREAM_CLOSE = "dream.close" - DREAM_TRASH = "dream.trash" DREAM_INPUTS = "dream.inputs" DREAM_TABLES = "dream.tables" @@ -323,7 +329,7 @@ func init() { list := []string{cli.LINUX, cli.DARWIN, cli.WINDOWS} msg := m.Spawn(ice.Maps{ice.MSG_DAEMON: ""}) func() { - defer ToastProcess(m, ice.Info.Pathname)(ice.Info.Pathname) + defer ToastProcess(m, PUBLISH, ice.Info.Pathname)(PUBLISH, ice.Info.Pathname) m.Cmd(AUTOGEN, BINPACK) kit.For(list, func(goos string) { PushNoticeRich(m, mdb.NAME, ice.Info.NodeName, msg.Cmd(COMPILE, goos, cli.AMD64).AppendSimple()) diff --git a/base/web/html/html.go b/base/web/html/html.go index d7d1250a..26c50b79 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -64,9 +64,13 @@ const ( PROFILE = "profile" DISPLAY = "display" + TEXT = "text" + TEXTAREA = "textarea" + PASSWORD = "password" + SELECT = "select" + BUTTON = "button" + VIEW = "view" - TEXT = "text" - BUTTON = "button" INPUT = "input" VALUE = "value" OUTPUT = "output" diff --git a/base/web/matrix.css b/base/web/matrix.css index 7ca55fc7..6dd2d151 100644 --- a/base/web/matrix.css +++ b/base/web/matrix.css @@ -20,7 +20,6 @@ fieldset.web.matrix>div.output>table.content div.item.danger div.status div.item fieldset.web.matrix>div.output>table.content div.item.notice div.status div.item { color:var(--notice-fg-color); } 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 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 td:first-child { background-color:var(--plugin-bg-color); position:sticky; left:2px; } body:not(.mobile) fieldset.web.matrix>div.output>table.content tr.danger td:first-child { background-color:transparent; } diff --git a/base/web/option.go b/base/web/option.go index 6fe2751f..e8811e82 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -3,7 +3,6 @@ package web import ( "net/url" "strings" - "time" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" @@ -79,8 +78,12 @@ func PushNotice(m *ice.Message, arg ...ice.Any) { }) m.Cmd(SPACE, m.Option(ice.MSG_DAEMON), arg, opts) } -func PushNoticeRefresh(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("refresh", arg)...) } -func PushNoticeToast(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("toast", arg)...) } +func PushNoticeToast(m *ice.Message, arg ...ice.Any) { + PushNotice(m, kit.List(TOAST, arg)...) +} +func PushNoticeRefresh(m *ice.Message, arg ...ice.Any) { + PushNotice(m, kit.List("refresh", arg)...) +} func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { PushNotice(m.StatusTimeCount(), kit.List("grow", arg)...) } @@ -91,72 +94,35 @@ func PushStream(m *ice.Message) *ice.Message { m.Options(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) { PushNoticeGrow(m, string(buf)) }, nil)).ProcessHold(toastContent(m, ice.SUCCESS)) return m } -func init() { ice.Info.PushStream = PushStream } func init() { ice.Info.PushNotice = PushNotice } +func init() { ice.Info.PushStream = PushStream } -func Toast(m *ice.Message, text string, arg ...ice.Any) *ice.Message { // [title [duration [progress [hash]]]] - if len(arg) > 1 { - switch val := arg[1].(type) { - case string: - if value, err := time.ParseDuration(val); err == nil { - arg[1] = int(value / time.Millisecond) - } - } - } - kit.If(len(arg) == 0, func() { arg = append(arg, m.PrefixKey()) }) - kit.If(len(arg) > 0 && arg[0] == "", func() { - arg[0] = kit.Keys(m.Option(ice.MSG_USERPOD0), m.Option(ice.MSG_USERPOD), ctx.ShortCmd(m.PrefixKey())) - }) - PushNoticeToast(m, text, arg) - return m -} - -var Icons = map[string]string{ice.PROCESS: "🕑", ice.FAILURE: "❌", ice.SUCCESS: "✅"} - -func toastContent(m *ice.Message, state string, arg ...ice.Any) string { - if len(arg) == 0 { - return kit.JoinWord(kit.Simple(Icons[state], kit.Select(ice.LIST, m.ActionKey()), state)...) - } else { - return kit.JoinWord(kit.Simple(Icons[state], arg)...) - } -} -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, cli.TIME_3s)).Sleep(m.OptionDefault(ice.TOAST_DURATION, cli.TIME_3s)) -} -func ToastProcess(m *ice.Message, arg ...ice.Any) func(...ice.Any) { - h := kit.HashsUniq() - Toast(m, toastContent(m, ice.PROCESS, arg...), "", "-1", "", h) - return func(arg ...ice.Any) { Toast(m, toastContent(m, ice.SUCCESS, arg...), "", cli.TIME_3s, "", h) } -} -func GoToastTable(m *ice.Message, key string, cb func(value ice.Maps)) *ice.Message { - if m.Length() == 0 { +func ProcessIframe(m *ice.Message, title, link string, arg ...string) *ice.Message { + if m.IsMetaKey() { + m.ProcessOpen(link) return m } - return GoToast(m, func(toast func(string, int, int)) []string { - m.Table(func(value ice.Maps, index, total int) { toast(value[key], index, total); cb(value) }) - return nil - }) + if !kit.HasPrefixList(arg, ctx.RUN) { + defer m.Push(TITLE, title) + } + return ctx.ProcessFloat(m, CHAT_IFRAME, link, arg...) } -func GoToast(m *ice.Message, cb func(toast func(name string, count, total int)) []string) *ice.Message { - icon, _total, h := Icons[ice.PROCESS], 1, kit.HashsUniq() - toast := func(name string, count, total int) { - kit.If(total == 0, func() { total = 1 }) - Toast(m, kit.Format("%s %s %s", icon, kit.JoinWord(kit.Select(ice.LIST, m.ActionKey()), name), strings.ReplaceAll(kit.FmtSize(count, total), "B", "")), - m.Option(ice.MSG_TITLE), m.OptionDefault(ice.TOAST_DURATION, "-1"), count*100/total, h) - _total = total - } - if list := cb(toast); len(list) > 0 { - icon = Icons[ice.FAILURE] - m.Option(ice.TOAST_DURATION, cli.TIME_30s) - toast(kit.JoinWord(list...), len(list), _total) +func ProcessPodCmd(m *ice.Message, pod, cmd string, args ice.Any, arg ...string) *ice.Message { + if kit.HasPrefixList(arg, ctx.RUN) { + ctx.ProcessField(m.Options(ice.POD, arg[1]), arg[2], args, kit.Simple(arg[0], arg[3:])...) } else { - icon = Icons[ice.SUCCESS] - m.Option(ice.TOAST_DURATION, cli.TIME_3s) - toast(ice.SUCCESS, _total, _total) + ctx.ProcessField(m.Options(ice.POD, pod), cmd, args, arg...).ProcessField(ctx.ACTION, m.ActionKey(), ctx.RUN, pod, cmd) } - m.Sleep(m.Option(ice.TOAST_DURATION)) return m } +func ProcessHashPodCmd(m *ice.Message, arg ...string) *ice.Message { + msg := m + if kit.HasPrefixList(arg, ctx.RUN) { + msg = mdb.HashSelects(m.Spawn(), arg[1]) + arg = kit.Simple(arg[0], arg[2:]) + } else { + msg = mdb.HashSelects(m.Spawn(), m.Option(mdb.HASH)) + defer m.ProcessField(ctx.ACTION, m.ActionKey(), ctx.RUN, m.Option(mdb.HASH)) + } + return ctx.ProcessField(m.Options(ice.POD, msg.Append(SPACE)), msg.Append(ctx.INDEX), kit.Split(msg.Append(ctx.ARGS)), arg...) +} diff --git a/base/web/share.go b/base/web/share.go index 0d08e6bb..43409cc5 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -60,12 +60,11 @@ const ( STORM = "storm" FIELD = "field" - LOCAL = "local" PROXY = "proxy" - TOAST = "toast" + LOCAL = "local" - SHARE_LOCAL = "/share/local/" SHARE_CACHE = "/share/cache/" + SHARE_LOCAL = "/share/local/" ) const SHARE = "share" @@ -128,12 +127,9 @@ func init() { mdb.HashSelect(m, arg...).PushAction(OPEN, mdb.REMOVE) } }}, + PP(SHARE, PROXY): {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }}, PP(SHARE, CACHE): {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }}, PP(SHARE, LOCAL): {Hand: func(m *ice.Message, arg ...string) { ShareLocalFile(m, arg...) }}, - PP(SHARE, PROXY): {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }}, - PP(SHARE, TOAST): {Hand: func(m *ice.Message, arg ...string) { - m.Options(ice.LOG_DISABLE, ice.TRUE).Cmdy(SPACE, arg[0], kit.UnMarshal(m.Option(ice.ARG))) - }}, }) } func IsNotValidShare(m *ice.Message, time string) bool { diff --git a/base/web/spide.go b/base/web/spide.go index d25d9451..bcedfb89 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -467,13 +467,3 @@ 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.ProcessOpen(link) - return m - } - if !kit.HasPrefixList(arg, ctx.RUN) { - defer m.Push(TITLE, title) - } - return ctx.ProcessFloat(m, CHAT_IFRAME, link, arg...) -} diff --git a/base/web/web.go b/base/web/web.go index 2dab6c2f..49e89b32 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -79,9 +79,9 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块"} func init() { ice.Index.Register(Index, &Frame{}, - BROAD, SERVE, SPACE, ROUTE, DREAM, STORE, - SHARE, TOKEN, SPIDE, CACHE, ADMIN, STATS, COUNT, - MATRIX, + BROAD, SERVE, SPACE, DREAM, ROUTE, + SHARE, TOKEN, STATS, COUNT, TOAST, + SPIDE, CACHE, STORE, ADMIN, MATRIX, ) } diff --git a/core/chat/favor.go b/core/chat/favor.go index 23d3c185..df8c0a9b 100644 --- a/core/chat/favor.go +++ b/core/chat/favor.go @@ -119,27 +119,21 @@ func FavorAction() ice.Actions { } func FavorPreview(m *ice.Message, arg ...string) { if kit.HasPrefixList(arg, ctx.RUN) { - if pod := arg[1]; pod != "" { - arg[1] = "" - m.Options(ice.MSG_USERPOD, pod).Cmdy(web.SPACE, pod, m.CommandKey(), ctx.ACTION, m.ActionKey(), arg) + web.ProcessPodCmd(m, "", "", nil, arg...) + } else { + msg := m + if m.Option(web.SPACE) == "" { + msg = mdb.HashSelects(m.Spawn(), m.Option(mdb.HASH)) } else { - index, args := favorPreview(m, arg[2], arg...) - ctx.ProcessField(m, index, args, kit.Simple(ctx.RUN, arg[3:])...) + msg = m.Cmd(web.SPACE, m.Option(web.SPACE), m.PrefixKey(), m.Option(mdb.HASH)) } - } else if !web.PodCmd(m, web.SPACE, kit.Simple(ctx.ACTION, m.ActionKey(), arg)...) { - index, args := favorPreview(m, m.Option(mdb.HASH), arg...) - ctx.ProcessField(m, index, args, arg...).Push(ice.MSG_SPACE, m.Option(ice.MSG_USERPOD)) - m.Option(ice.FIELD_PREFIX, ctx.ACTION, m.ActionKey(), ctx.RUN, m.Option(ice.MSG_USERPOD), m.Option(mdb.HASH)) + index, args := msg.Append(mdb.TYPE), kit.Split(msg.Append(mdb.TEXT)) + switch msg.Append(mdb.TYPE) { + case ctx.INDEX: + index = msg.Append(mdb.NAME) + case nfs.SHY: + index = web.WIKI_WORD + } + web.ProcessPodCmd(m, m.Option(web.SPACE), index, args, arg...) } } -func favorPreview(m *ice.Message, h string, arg ...string) (string, []string) { - msg := mdb.HashSelects(m.Spawn(), h) - index, args := msg.Append(mdb.TYPE), kit.Split(msg.Append(mdb.TEXT)) - switch msg.Append(mdb.TYPE) { - case ctx.INDEX: - index = msg.Append(mdb.NAME) - case nfs.SHY: - index = web.WIKI_WORD - } - return index, args -} diff --git a/core/chat/location/location.js b/core/chat/location/location.js index 640ee3b4..ea2587bc 100644 --- a/core/chat/location/location.js +++ b/core/chat/location/location.js @@ -5,7 +5,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) {}, can.onmotion.hidden(can, can._action) // can.core.Item(can.ui.zone, function(key, item) { key == "favor" || item._legend.click() }) if (can.user.isMobile) { - can.page.style(can, can.ui.project, "z-index", 10, "position", "absolute", html.MAX_HEIGHT, can.ConfHeight()-120) + can.page.style(can, can.ui.project, "z-index", 2, "position", "absolute", html.MAX_HEIGHT, can.ConfHeight()-120) can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()) can.onmotion.hidden(can, can._action), can.onmotion.hidden(can, can._status) } else { diff --git a/core/chat/macos/desktop.css b/core/chat/macos/desktop.css index 719a497e..efbf9e97 100644 --- a/core/chat/macos/desktop.css +++ b/core/chat/macos/desktop.css @@ -3,7 +3,7 @@ fieldset.macos.desktop { background-size:cover; background-position:center; } fieldset.macos.desktop>div.output { background-color:transparent; overflow:hidden; } fieldset.macos.desktop>div.output>fieldset.macos { background-color:var(--plugin-bg-color); } fieldset.macos.desktop>div.output>fieldset.macos>div.output { background-color:transparent; } -fieldset.macos.desktop>div.output>fieldset.macos.menu { line-height:var(--desktop-menu-height); border-radius:0; height:var(--desktop-menu-height); width:100%; position:sticky; top:0; overflow:hidden; } +fieldset.macos.desktop>div.output>fieldset.macos.menu { line-height:var(--desktop-menu-height); border-radius:0; height:var(--desktop-menu-height); width:100%; position:sticky; top:0; overflow:hidden; z-index:10; } fieldset.macos.desktop>div.output>fieldset.macos.menu div.menu:hover { background-color:var(--hover-bg-color); } fieldset.macos.desktop>div.output>fieldset.macos.menu div.menu.icon { font-size:24px; line-height:22px; height:var(--desktop-menu-height); } fieldset.macos.desktop>div.output>fieldset.macos.menu div.menu img { height:var(--desktop-menu-height); margin-right:var(--input-padding); } @@ -11,9 +11,9 @@ fieldset.macos.desktop>div.output>fieldset.macos.menu div.menu { display:flex; a fieldset.macos.desktop>div.output>fieldset.macos.menu div.menu.title { font-style:italic; margin-left:10px; } fieldset.macos.desktop>div.output>fieldset.macos.menu div.item.time { margin-right:10px; } fieldset.macos.desktop>div.output>fieldset.macos.menu>div.output { overflow:hidden; } -fieldset.macos.desktop>div.output>fieldset.macos.dock { border:var(--box-border); border-radius:var(--plugin-radius); position:absolute; bottom:var(--input-margin); transition:margin-left 0.3s; z-index:11; } -fieldset.macos.desktop>div.output>fieldset.macos.searchs { position:absolute; z-index:11; } -fieldset.macos.desktop>div.output>fieldset.macos.notifications { height:calc(100% - 125px); width:320px; overflow:auto; position:absolute; top:var(--desktop-menu-height); left:calc(100% - 320px); z-index:11; } +fieldset.macos.desktop>div.output>fieldset.macos.dock { border:var(--box-border); border-radius:var(--plugin-radius); position:absolute; bottom:var(--input-margin); transition:margin-left 0.3s; z-index:10; } +fieldset.macos.desktop>div.output>fieldset.macos.searchs { position:absolute; z-index:10; } +fieldset.macos.desktop>div.output>fieldset.macos.notifications { height:calc(100% - 125px); width:320px; overflow:auto; position:absolute; top:var(--desktop-menu-height); left:calc(100% - 320px); z-index:10; } fieldset.macos.desktop>div.output>fieldset.macos.notifications>div.action>div.item { padding:0; } fieldset.macos.desktop>div.output>fieldset.macos.notifications>div.output>div.item { clear:both; display:flex; padding:var(--input-padding)} fieldset.macos.desktop>div.output>fieldset.macos.notifications>div.output>div.item:not(:last-child) { border-bottom:var(--box-border); } @@ -30,7 +30,7 @@ fieldset.macos.desktop>div.output>div.desktop>div.item { text-align:center; } fieldset.macos.desktop>div.output>div.desktop>div.item img { object-fit:contain; height:var(--desktop-icon-size); width:var(--desktop-icon-size); } fieldset.macos.desktop>div.output>div.desktop>div.item>div.name { font-size:var(--code-font-size); width:var(--desktop-icon-size); overflow:hidden; } fieldset.macos.desktop>div.output>div.desktop>fieldset { border-radius:var(--plugin-radius); position:absolute; } -fieldset.macos.desktop>div.output>div.desktop>fieldset.select { z-index:1; } +fieldset.macos.desktop>div.output>div.desktop>fieldset.select { z-index:9; } fieldset.macos.desktop>div.output>div.desktop>fieldset>div.item.button { border-radius:var(--plugin-radius); box-shadow:var(--box-shadow); padding:8px; height:23px; width:23px; scale:0.7; position:absolute; top:10px; right:var(--plugin-padding); cursor:pointer; } fieldset.macos.desktop>div.output>div.desktop>fieldset>div.item.button:not(:hover)>span { display:none; } fieldset.macos.desktop>div.output>div.desktop>fieldset>legend { padding:0 var(--input-padding); margin:var(--button-margin); box-shadow:none; } diff --git a/core/chat/message.css b/core/chat/message.css index a780adfa..004f830d 100644 --- a/core/chat/message.css +++ b/core/chat/message.css @@ -1,7 +1,7 @@ body.light fieldset.web.chat.message>div.output { background-color:white; } body.light fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list { background-color:#e3e3e2; } body.light fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item:not(.plug).myself div.content { background-color:#94ec69; } -fieldset.web.chat.message>div.output>div.project>div.title { padding:var(--button-padding); display:flex; justify-content:space-between; position:sticky; top:0; z-index:10; } +fieldset.web.chat.message>div.output>div.project>div.title { padding:var(--button-padding); display:flex; justify-content:space-between; position:sticky; top:0; z-index:2; } fieldset.web.chat.message>div.output>div.project>div.title i:hover { background-color:var(--hover-bg-color); cursor:pointer; } fieldset.web.chat.message>div.output>div.project>div.title span:hover { background-color:var(--hover-bg-color); cursor:pointer; } fieldset.web.chat.message>div.output>div.project>div.item.text.filter>i { left:var(--input-padding); } @@ -12,7 +12,7 @@ fieldset.web.chat.message>div.output>div.project>div.item div.container { paddin fieldset.web.chat.message>div.output>div.project>div.item div.title { display:flex; justify-content:space-between; } fieldset.web.chat.message>div.output>div.project>div.item div.content { color:var(--disable-fg-color); font-size:var(--status-font-size); } fieldset.web.chat.message>div.output>div.layout>div.layout>div.content { overflow:hidden; } -fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.title { padding:var(--button-padding); display:flex; justify-content:space-between; position:sticky; top:0; z-index:10; } +fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.title { padding:var(--button-padding); display:flex; justify-content:space-between; position:sticky; top:0; z-index:2; } fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.title i:hover { background-color:var(--hover-bg-color); cursor:pointer; } fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.title span:hover { background-color:var(--hover-bg-color); cursor:pointer; } fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item { padding:var(--input-padding); min-height:fit-content; display:flex; } diff --git a/info.go b/info.go index 7498b035..32197ee1 100644 --- a/info.go +++ b/info.go @@ -175,13 +175,6 @@ func MergeActions(arg ...Any) Actions { return list } func SplitCmd(name string, actions Actions) (list []Any) { - const ( - TEXT = "text" - TEXTAREA = "textarea" - PASSWORD = "password" - SELECT = "select" - BUTTON = "button" - ) const ( RUN = "run" REFRESH = "refresh" @@ -191,10 +184,11 @@ func SplitCmd(name string, actions Actions) (list []Any) { PAGE = "page" ARGS = "args" CONTENT = "content" + FILTER = "filter" ) item, button := kit.Dict(), false push := func(arg ...string) { - button = kit.Select("", arg, 0) == BUTTON + button = kit.Select("", arg, 0) == html.BUTTON item = kit.Dict(TYPE, kit.Select("", arg, 0), NAME, kit.Select("", arg, 1), ACTION, kit.Select("", arg, 2)) list = append(list, item) } @@ -202,27 +196,29 @@ func SplitCmd(name string, actions Actions) (list []Any) { for i := 1; i < len(ls); i++ { switch ls[i] { case RUN: - push(BUTTON, ls[i]) + push(html.BUTTON, ls[i]) case REFRESH: - push(BUTTON, ls[i], AUTO) + push(html.BUTTON, ls[i], AUTO) case LIST: - push(BUTTON, ls[i], AUTO) + push(html.BUTTON, ls[i], AUTO) case AUTO: - push(BUTTON, LIST, AUTO) - push(BUTTON, BACK) + push(html.BUTTON, LIST, AUTO) + push(html.BUTTON, BACK) case PAGE: - push(BUTTON, "prev") - push(BUTTON, "next") - push(TEXT, "offend") - push(TEXT, "limit") - case ARGS, CONTENT, TEXTAREA, TEXT, "extra": - push(TEXTAREA, ls[i]) - case PASSWORD: - push(PASSWORD, ls[i]) + push(html.BUTTON, "prev") + push(html.BUTTON, "next") + push(html.TEXT, "offend") + push(html.TEXT, "limit") + case ARGS, CONTENT, html.TEXTAREA, html.TEXT, "extra": + push(html.TEXTAREA, ls[i]) + case html.PASSWORD: + push(html.PASSWORD, ls[i]) + case FILTER: + push(html.TEXT, ls[i]) case "*": item["need"] = "must" case DF: - if item[TYPE] = kit.Select("", ls, i+1); item[TYPE] == BUTTON { + if item[TYPE] = kit.Select("", ls, i+1); item[TYPE] == html.BUTTON { button = true } i++ @@ -244,7 +240,7 @@ func SplitCmd(name string, actions Actions) (list []Any) { item[ACTION] = kit.Select("", ls, i+1) i++ default: - push(kit.Select(TEXT, BUTTON, button || actions != nil && actions[ls[i]] != nil), ls[i]) + push(kit.Select(html.TEXT, html.BUTTON, button || actions != nil && actions[ls[i]] != nil), ls[i]) } } return list diff --git a/meta.go b/meta.go index da94c394..3a9458c8 100644 --- a/meta.go +++ b/meta.go @@ -300,14 +300,22 @@ func (m *Message) Sort(key string, arg ...Any) *Message { switch v := arg[i].(type) { case string: cmp = v - case map[string]int: - order[k] = v case []string: list := map[string]int{} for i, v := range v { list[v] = i + 1 } order[k] = list + case map[string]int: + order[k] = v + case func(string) int: + list := map[string]int{} + kit.For(m.Appendv(k), func(k string) { + if _, ok := list[k]; !ok { + list[k] = v(k) + } + }) + order[k] = list } } if cmp == "" {