1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-28 02:02:02 +08:00

add chat.message

This commit is contained in:
IT 老营长 @云轩领航-创始人 2024-01-24 19:15:31 +08:00
parent 61b601c3c4
commit e668707738
8 changed files with 252 additions and 32 deletions

View File

@ -424,9 +424,7 @@ func init() {
func DreamAction() ice.Actions {
return ice.MergeActions(ice.Actions{
DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) {
DreamProcess(m, nil, arg...)
}},
DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { DreamProcess(m, nil, arg...) }},
}, gdb.EventsAction(DREAM_OPEN, DREAM_CLOSE, DREAM_INPUTS, DREAM_CREATE, DREAM_TRASH, DREAM_TABLES, DREAM_ACTION, SERVE_START))
}
func DreamProcess(m *ice.Message, args ice.Any, arg ...string) {

View File

@ -295,16 +295,16 @@ func init() {
Index.MergeCommands(ice.Commands{
// SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run create", Help: "蜘蛛侠", Actions: ice.MergeActions(ice.Actions{
SPIDE: {Help: "蜘蛛侠", Meta: kit.Dict(ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict(
CLIENT_TYPE, "类型",
CLIENT_NAME, "名称", CLIENT_URL, "地址",
CLIENT_TYPE, "类型", CLIENT_NAME, "名称", CLIENT_URL, "地址",
CLIENT_METHOD, "方法", CLIENT_ORIGIN, "服务", CLIENT_TIMEOUT, "超时",
CLIENT_PROTOCOL, "协议", CLIENT_HOST, "主机", CLIENT_HOSTNAME, "机器",
))), Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
conf := mdb.Confm(m, cli.RUNTIME, cli.CONF)
dev := kit.Select("https://2021.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV])
m.Cmd("", mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com", conf[cli.CTX_SHY]), nfs.REPOS)
m.Cmd("", mdb.CREATE, ice.DEV, kit.Select("https://2021.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV]), nfs.REPOS)
m.Cmd("", mdb.CREATE, "dev_ip", kit.Select("https://2021.shylinux.com", os.Getenv("ctx_dev_ip")), nfs.REPOS)
m.Cmd("", mdb.CREATE, ice.DEV, dev, nfs.REPOS)
m.Cmd("", mdb.CREATE, ice.DEV_IP, kit.Select(dev, os.Getenv("ctx_dev_ip")), nfs.REPOS)
m.Cmd("", mdb.CREATE, ice.OPS, kit.Select("http://localhost:9020", conf[cli.CTX_OPS]), nfs.REPOS)
m.Cmd("", mdb.CREATE, ice.DEMO, kit.Select("http://localhost:20000", conf[cli.CTX_DEMO]))
m.Cmd("", mdb.CREATE, ice.MAIL, kit.Select("https://mail.shylinux.com", conf[cli.CTX_MAIL]))

View File

@ -5,10 +5,12 @@ import (
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"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"
)
@ -16,15 +18,14 @@ const STORE = "store"
func init() {
Index.MergeCommands(ice.Commands{
STORE: {Name: "store", Help: "系统商店", Actions: ice.MergeActions(ice.Actions{
STORE: {Name: "store", Help: "系统商店", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
m.Cmds(SPIDE).Table(func(value ice.Maps) { kit.If(value[CLIENT_TYPE] == nfs.REPOS, func() { m.Push("", value, arg[0]) }) })
}},
mdb.CREATE: {Name: "create name* origin*", Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.TYPE, nfs.REPOS)
m.Cmd(SPIDE, mdb.CREATE, m.OptionSimple("name,origin,type"))
m.Cmd(SPIDE, mdb.CREATE, m.OptionSimple("name,origin"), mdb.TYPE, nfs.REPOS)
}},
"install": {Help: "安装", Hand: func(m *ice.Message, arg ...string) {
"install": {Hand: func(m *ice.Message, arg ...string) {
if !kit.HasPrefixList(arg, ctx.RUN) {
if !nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) {
if strings.HasPrefix(m.Option(mdb.ICON), nfs.REQUIRE) {
@ -39,31 +40,36 @@ func init() {
ctx.ProcessField(m, CHAT_IFRAME, S(m.Option(mdb.NAME)), arg...)
}},
OPEN: {Hand: func(m *ice.Message, arg ...string) {
if !kit.HasPrefixList(arg, ctx.RUN) {
defer m.Push("title", m.Option(mdb.NAME))
}
ctx.ProcessField(m, CHAT_IFRAME, S(m.Option(mdb.NAME)), arg...)
kit.If(!kit.HasPrefixList(arg, ctx.RUN), func() { m.Push("title", m.Option(mdb.NAME)) })
}},
PORTAL: {Help: "官网", Hand: func(m *ice.Message, arg ...string) {
if !kit.HasPrefixList(arg, ctx.RUN) {
defer m.Push("title", m.Option(mdb.NAME))
}
PORTAL: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessField(m, CHAT_IFRAME, m.Option(ORIGIN)+S(m.Option(mdb.NAME))+C(PORTAL), arg...)
kit.If(!kit.HasPrefixList(arg, ctx.RUN), func() { m.Push("title", m.Option(mdb.NAME)) })
}},
}, ctx.ConfAction(ctx.TOOLS, DREAM)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmdy(SPIDE, arg, kit.Dict(ice.MSG_FIELDS, "time,client.type,client.name,client.origin")).Action(mdb.CREATE).Display("")
m.Cmd(SPIDE, arg, kit.Dict(ice.MSG_FIELDS, "time,client.type,client.name,client.origin")).Table(func(value ice.Maps) {
if value[CLIENT_TYPE] == nfs.REPOS && value[CLIENT_NAME] != ice.OPS {
m.Push(mdb.NAME, value[CLIENT_NAME])
}
})
m.Action(html.FILTER, mdb.CREATE).Display("")
ctx.Toolkit(m)
} else {
origin := SpideOrigin(m, arg[0])
m.SetAppend().SplitIndex(m.Cmdx(SPIDE, arg[0], C(DREAM))).Table(func(value ice.Maps) {
if !nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME])) {
m.SetAppend().Spawn().SplitIndex(m.Cmdx(SPIDE, arg[0], C(DREAM))).Table(func(value ice.Maps) {
if value[mdb.TYPE] != WORKER {
return
}
m.Push("", value, kit.Split("time,name,icon,repos,binary,module,version"))
if m.Push(ORIGIN, origin); !nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME])) {
m.PushButton("install", PORTAL)
} else {
m.PushButton(OPEN, PORTAL)
}
m.Push(ORIGIN, origin)
})
m.StatusTimeCount(ORIGIN, origin)
}
}},
})

View File

@ -1,21 +1,24 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.ui = can.onappend.layout(can), can.onappend.style(can, "output card", can.ui.content), can.onimport._project(can, msg)
can.ui = can.onappend.layout(can), can.onimport._project(can, msg), can.onappend.style(can, "output card", can.ui.content)
can.onmotion.delay(can, function() { can.onimport.layout(can) })
can.sup.onimport._field = function(sup, msg) { msg.Table(function(item) {
can.onappend._plugin(can, item, {style: html.FLOAT}, function(sub) {})
}) }
},
_project: function(can, msg) { var select
msg.Table(function(value) { if (value["client.type"] != nfs.REPOS) { return } value.name = `${value["client.name"]}`
var _target = can.onimport.item(can, value, function(event) {
if (can.onmotion.cache(can, function() { return value.name }, can.ui.content)) { return can.onimport.layout(can) }
can.run(event, [value.name], function(msg) { can.onimport._content(can, msg), can.onimport.layout(can) })
}, function() {}, can.ui.project); select = (value.name == ice.DEV? _target: select)||_target
_project: function(can, msg) { var select, current = can.db.hash[0]||ice.DEV
msg.Table(function(value) {
var _target = can.onimport.item(can, value, function(event) { can.isCmdMode() && can.misc.SearchHash(can, value.name)
if (can.onmotion.cache(can, function() { return value.name }, can.ui.content, can._status)) { return can.onimport.layout(can) }
can.run(event, [value.name], function(msg) {
can.onappend._status(can, msg.Option(ice.MSG_STATUS))
can.onimport._content(can, msg), can.onimport.layout(can)
})
}, function() {}, can.ui.project); select = (value.name == current? _target: select)||_target
}), select && select.click()
},
_content: function(can, msg) { var year = new Date().getFullYear()+"-"
can.page.Appends(can, can.ui.content, msg.Table(function(value) { if (value.type != web.WORKER) { return }
_content: function(can, msg) {
can.page.Appends(can, can.ui.content, msg.Table(function(value) {
var icon = value.icon; if (can.base.beginWith(value.icon, nfs.PS)) { icon = value.origin+value.icon }
return {view: [[html.ITEM, value.status]], list: [
{view: [wiki.TITLE, html.DIV], list: [{img: icon}, {view: mdb.NAME, list: [
@ -25,7 +28,7 @@ Volcanos(chat.ONIMPORT, {
// {icon: "bi bi-share"}, {text: value.forks_count||"0"},
// {icon: "bi bi-star"}, {text: value.stars_count||"0"},
{icon: "bi bi-folder2"}, {text: value.version.split("-").slice(0, 2).join("-")},
{icon: "bi bi-clock"}, {text: can.base.trimPrefix(value.time.split(":").slice(0, 2).join(":"), year)},
{icon: "bi bi-clock"}, {text: can.base.TimeTrim(value.time)},
]}
]}]}, {view: [wiki.CONTENT, html.DIV, value.description]},
{view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, 5) }},
@ -33,6 +36,7 @@ Volcanos(chat.ONIMPORT, {
}))
},
layout: function(can) {
can.Action(html.FILTER) && can.onmotion.filter(can, can.Action(html.FILTER))
can.user.isMobile && can.onmotion.toggle(can, can.ui.project, can.user.isLandscape())
can.ui.layout(can.ConfHeight(), can.ConfWidth()), can.onlayout.expand(can, can.ui.content, 320)
},

View File

@ -1,6 +1,8 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) {},
_layout_init: function(can, msg, cb) {
can.db.list = {}, can.ui = can.onappend.layout(can), can.onimport._project(can)
can.onmotion.hidden(can, can.ui.project)
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)

45
core/chat/message.css Normal file
View File

@ -0,0 +1,45 @@
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.item { height:58px; padding:var(--input-padding); }
fieldset.web.chat.message>div.output>div.project>div.item img { height:var(--header-height); width:var(--header-height); display:block; float:left; }
fieldset.web.chat.message>div.output>div.project>div.item span.time { color:var(--disable-fg-color); font-size:var(--status-font-size); }
fieldset.web.chat.message>div.output>div.project>div.item div.container { width:calc(100% - var(--header-height)); float:left; }
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 {
font-size:24px; 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 i:hover {
background-color:var(--hover-bg-color); cursor:pointer;
}
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 i: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; align-items:center; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item:hover { background-color:unset; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.time { color:var(--disable-fg-color); font-size:var(--status-font-size); padding:0; height:fit-content; justify-content:center; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item>img { height:var(--header-height); width:var(--header-height); }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item div.content img { max-width:256px; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item div.container { width:fit-content; max-width:calc(100% - var(--header-height)); margin:0 var(--button-margin); }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item div.container>span.from { color:var(--disable-fg-color); font-size:var(--status-font-size); padding:0 var(--input-padding); }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.myself div.container>span.from { float:right; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.myself div.container { display:flex; flex-direction:column; align-items:flex-end; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item div.content {
display:flex; align-items:center; padding:var(--input-padding) var(--button-padding); border-radius:5px; min-height:var(--header-height); width:fit-content;
}
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.plug { height:fit-content; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.plug div.content { padding:0; }
fieldset.web.chat.message>div.output>div.layout>div.layout>div.content>div.list>div.item.myself { flex-direction:row-reverse; }
fieldset.web.chat.message>div.output>div.layout>div.display { height:120px; overflow:hidden; }
fieldset.web.chat.message>div.output>div.layout>div.display div.toolkit { height:var(--action-height); display:flex; }
fieldset.web.chat.message>div.output>div.layout>div.display div.toolkit i { padding:var(--input-padding); }
fieldset.web.chat.message>div.output>div.layout>div.display div.toolkit i:hover { background-color:var(--hover-bg-color); }
fieldset.web.chat.message>div.output>div.layout>div.display textarea { height:calc(100% - var(--action-height)); }

56
core/chat/message.go Normal file
View File

@ -0,0 +1,56 @@
package chat
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
const MESSAGE = "message"
func init() {
Index.MergeCommands(ice.Commands{
MESSAGE: {Name: "message", Help: "消息", Icon: "Messages.png", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
messageCreate(m, web.DREAM, "usr/icons/Launchpad.png")
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.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),
))
}},
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,avatar,usernick,username,type,name,text,space,index,args",
)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
mdb.ZoneSelect(m.Spawn(), arg...).Table(func(value ice.Maps) {
if kit.IsIn(m.Option(ice.MSG_USERROLE), value[mdb.TYPE], aaa.TECH, aaa.ROOT) {
m.PushRecord(value, mdb.Config(m, mdb.FIELD))
}
})
} else {
mdb.ZoneSelect(m, arg...)
}
m.Display("")
}},
})
}
func messageCreate(m *ice.Message, name, icon string) {
kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, name, "meta.time"), m.Time())
kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, name, "meta.type"), aaa.TECH)
kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, name, "meta.name"), name)
kit.Value(m.Target().Configs[m.CommandKey()].Value, kit.Keys(mdb.HASH, name, "meta.icons"), icon)
}
func messageInsert(m *ice.Message, zone string, arg ...string) {
m.Cmd("", mdb.INSERT, zone, arg, ice.Maps{ice.MSG_USERNAME: zone})
}

109
core/chat/message.js Normal file
View File

@ -0,0 +1,109 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { 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
can.isCmdMode() && can.page.insertBefore(can, [{view: "title", list: [
{icon: "bi bi-three-dots", onclick: function() { can.onmotion.toggle(can, can.ui.profile), can.onimport.layout(can) }},
{text: "message"||can.ConfIndex(), onclick: function(event) {
can._legend.onclick(event)
}},
{icon: "bi bi-plus-lg", onclick: function(event) {
can.Update(event, [ctx.ACTION, mdb.CREATE])
}},
]}], can.ui.project.firstChild, can.ui.project)
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: "container", list: [
{view: "title", list: [{text: value.name||"some"}, {text: [can.base.TimeTrim(value.time), "", mdb.TIME]}]},
{view: "content", list: [{text: value.text||"[未知消息]"}]},
]},
], onclick: function(event) { can.isCmdMode() && can.misc.SearchHash(can, value.name), 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() { return value.name }, can._status, can.ui.content, can.ui.profile, can.ui.display)) { return can.onimport.layout(can) }
can.run(event, [value.hash], function(msg) { can.onappend._status(can, msg.Option(ice.MSG_STATUS))
can.onimport._display(can), can.onimport._content(can, msg), can.onimport.layout(can)
})
}}])._target; select = (value.name == 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: "title", list: [
{icon: "bi bi-chevron-left", onclick: function() { can.onimport._switch(can, true) }},
{text: can.db.zone.name},
{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: "list"}])._target
msg.Table(function(value) { var myself = value.username == can.user.info.username
can.page.Append(can, can.ui.message, [{view: [[html.ITEM, mdb.TIME], "", can.base.TimeTrim(value.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: "container", list: [{text: [value.usernick, "", "from"]}, can.onfigure[value.type](can, value)]},
]}])
})
},
_display: function(can, msg) {
can.page.Appends(can, can.ui.display, [
{view: "toolkit", list: can.core.Item(can.ondetail, function(icon, cb) { return {icon: icon, onclick: function(event) { cb(event, can) }} }) },
{type: html.TEXTAREA, onkeyup: function(event) { if (event.key == "Enter" && event.ctrlKey) {
can.onimport._insert(can, [mdb.TYPE, "text", mdb.TEXT, event.target.value])
} }},
]), can.onmotion.toggle(can, can.ui.display, true)
},
_insert: function(can, args) {
can.runAction(event, mdb.INSERT, [can.db.hash].concat(args), function() {
can.run(event, [can.db.hash], function(msg) { can.onappend._status(can, msg.Option(ice.MSG_STATUS))
can.onimport._content(can, msg), can.onimport.layout(can)
})
})
},
_switch: function(can, project) { if (!can.user.isMobile) { return }
can.page.style(can, can.ui.project, html.WIDTH, can.ConfWidth())
can.page.style(can, can.ui.project, "flex", "0 0 "+can.ConfWidth()+"px")
can.onmotion.toggle(can, can.ui.project, project)
can.onmotion.toggle(can, can.ui.content, !project)
can.onmotion.toggle(can, can.ui.display, !project)
can.onimport.layout(can)
},
layout: function(can) { can.ui.layout(can.ConfHeight(), can.ConfWidth())
can.ui.title && can.page.style(can, can.ui.message, html.HEIGHT, can.ui.content.offsetHeight-can.ui.title.offsetHeight)
can.ui.message && (can.ui.message.scrollTop += 10000)
},
}, [""])
Volcanos(chat.ONDETAIL, {
"bi bi-mic": function(event, can) {},
"bi bi-card-image": function(event, can) {
can.user.input(event, can, [mdb.ICONS], function(args) {
can.onimport._insert(can, [mdb.TYPE, "image"].concat([mdb.TEXT, args[1]]))
})
},
"bi bi-camera": function(event, can) {},
"bi bi-camera-video": function(event, can) {},
"bi bi-file-earmark": function(event, can) {},
"bi bi-geo-alt": function(event, can) {},
"bi bi-window": function(event, can) {
can.user.input(event, can, [web.SPACE, ctx.INDEX, ctx.ARGS], function(args) {
can.onimport._insert(can, [mdb.TYPE, "plug"].concat(args))
})
},
})
Volcanos(chat.ONFIGURE, {
text: function(can, value) {
return {view: "content", list: [{text: value.text||"[未知消息]"}]}
},
image: function(can, value) {
return {view: "content", list: [{img: can.misc.Resource(can, value.text)}]}
},
plug: function(can, value) { value.type = "story"
var height = can.base.Min(can.ui.content.offsetHeight-210, 240)
var height = can.base.Max(320, height, height/(can.base.isIn(value.index, "iframe")? 1: 2)),
width = can.ui.content.offsetWidth-(can.user.isMobile? 60: 180)
return {view: "content", style: {height: height, width: width}, _init: function(target) {
can.onappend._plugin(can, value, {height: height, width: width}, function(sub) {
sub.onexport.output = function() { sub.onimport.size(sub, height, width)
can.page.style(can, target, html.HEIGHT, sub._target.offsetHeight, html.WIDTH, sub._target.offsetWidth)
}
}, target)
}}
},
})