Split into category packages; module github.com/ZacharyZhang-NY/MujicaUI
This commit is contained in:
1822 files changed
+24568
-21314
No files matched your search
@@ -7,7 +7,10 @@ import (
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
mujica "mujicaui"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/chat"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/core"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/display"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/input"
|
||||
)
|
||||
|
||||
const chatmsgCategory = "Chat Messages"
|
||||
@@ -26,7 +29,7 @@ var chatmsgReplies = []string{
|
||||
type chatmsgDemo struct {
|
||||
ids []string
|
||||
texts []string
|
||||
list mujica.MessageListState
|
||||
list chat.MessageListState
|
||||
next int
|
||||
sidebar bool
|
||||
dated bool
|
||||
@@ -54,27 +57,27 @@ func (d *chatmsgDemo) day(i int) time.Time {
|
||||
|
||||
// row shows message i as a bubble, users and the assistant taking turns.
|
||||
func (d *chatmsgDemo) row(c *ui.Context, i int) {
|
||||
role := mujica.MessageAssistant
|
||||
role := chat.MessageAssistant
|
||||
if i%2 == 0 {
|
||||
role = mujica.MessageUser
|
||||
role = chat.MessageUser
|
||||
}
|
||||
mujica.MessageBubble(c, role, mujica.MessageBubbleOptions{}, func() { mujica.MarkdownView(c, d.texts[i]) })
|
||||
chat.MessageBubble(c, role, chat.MessageBubbleOptions{}, func() { chat.MarkdownView(c, d.texts[i]) })
|
||||
}
|
||||
|
||||
// chatmsgControls adds messages to a demo chat and logs it.
|
||||
func chatmsgControls(c *ui.Context, log func(string), d *chatmsgDemo) {
|
||||
ui.Row(c).Gap(8).Children(func() {
|
||||
if mujica.Button(c, "Add message", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() {
|
||||
if input.Button(c, "Add message", input.ButtonOptions{Variant: input.Secondary}).Clicked() {
|
||||
d.add()
|
||||
log(fmt.Sprintf("message %s added", d.ids[len(d.ids)-1]))
|
||||
}
|
||||
if mujica.Button(c, "Add 10", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() {
|
||||
if input.Button(c, "Add 10", input.ButtonOptions{Variant: input.Secondary}).Clicked() {
|
||||
for range 10 {
|
||||
d.add()
|
||||
}
|
||||
log(fmt.Sprintf("10 messages added, %d in all", len(d.ids)))
|
||||
}
|
||||
if mujica.Button(c, "Jump to latest", mujica.ButtonOptions{Variant: mujica.Ghost}).Clicked() {
|
||||
if input.Button(c, "Jump to latest", input.ButtonOptions{Variant: input.Ghost}).Clicked() {
|
||||
d.list.ScrollToEnd()
|
||||
log("scrolled to end")
|
||||
}
|
||||
@@ -84,8 +87,8 @@ func chatmsgControls(c *ui.Context, log func(string), d *chatmsgDemo) {
|
||||
var chatmsgListPages = []page{
|
||||
{ID: "201", Name: "ChatContainer", ZhName: "对话容器", Category: chatmsgCategory,
|
||||
Keys: "Tab 在侧栏、消息与输入区之间移动;消息区滚轮与 PageUp/PageDown 滚动;上翻后出现回到最新按钮。",
|
||||
Code: `mujica.ChatContainer(c, &chat, len(msgs), mujica.ChatContainerOptions{
|
||||
List: mujica.MessageListOptions{ID: func(i int) string { return msgs[i] }},
|
||||
Code: `chat.ChatContainer(c, &thread, len(msgs), chat.ChatContainerOptions{
|
||||
List: chat.MessageListOptions{ID: func(i int) string { return msgs[i] }},
|
||||
Input: func() { ui.Text(c, "Composer goes here") },
|
||||
}, func(i int) { ui.Text(c, msgs[i]) })`,
|
||||
Demo: func(c *ui.Context, log func(string)) {
|
||||
@@ -96,11 +99,11 @@ var chatmsgListPages = []page{
|
||||
chatmsgControls(c, log, d)
|
||||
})
|
||||
inputSection(c, "Live", func() {
|
||||
ui.Box(c).Height(420).Border(1, mujica.Tokens(c).Border).Clip().Children(func() {
|
||||
opts := mujica.ChatContainerOptions{
|
||||
List: mujica.MessageListOptions{ID: func(i int) string { return d.ids[i] }},
|
||||
ui.Box(c).Height(420).Border(1, core.Tokens(c).Border).Clip().Children(func() {
|
||||
opts := chat.ChatContainerOptions{
|
||||
List: chat.MessageListOptions{ID: func(i int) string { return d.ids[i] }},
|
||||
Input: func() {
|
||||
r := mujica.TextInput(c, draft, mujica.TextInputOptions{Label: "Message", Placeholder: "Write to the herald"})
|
||||
r := input.TextInput(c, draft, input.TextInputOptions{Label: "Message", Placeholder: "Write to the herald"})
|
||||
if r.Submitted() && strings.TrimSpace(*draft) != "" {
|
||||
d.add()
|
||||
d.texts[len(d.texts)-1] = *draft
|
||||
@@ -118,7 +121,7 @@ var chatmsgListPages = []page{
|
||||
})
|
||||
}
|
||||
}
|
||||
r := mujica.ChatContainer(c, &d.list, len(d.ids), opts, func(i int) { d.row(c, i) })
|
||||
r := chat.ChatContainer(c, &d.list, len(d.ids), opts, func(i int) { d.row(c, i) })
|
||||
if r.Unread() > 0 {
|
||||
ui.Text(c, fmt.Sprintf("%d unread", r.Unread())).Absolute().Top(8).Right(12)
|
||||
}
|
||||
@@ -127,7 +130,7 @@ var chatmsgListPages = []page{
|
||||
}},
|
||||
{ID: "202", Name: "MessageList", ZhName: "消息列表", Category: chatmsgCategory,
|
||||
Keys: "滚轮与方向键滚动;上翻后停止跟随;Tab 到回到最新按钮,Enter 回到底部。",
|
||||
Code: `r := mujica.MessageList(c, &list, len(ids), mujica.MessageListOptions{
|
||||
Code: `r := chat.MessageList(c, &list, len(ids), chat.MessageListOptions{
|
||||
ID: func(i int) string { return ids[i] },
|
||||
}, func(i int) { ui.Text(c, "Message "+ids[i]) })
|
||||
fmt.Println("unread", r.Unread())`,
|
||||
@@ -137,7 +140,7 @@ fmt.Println("unread", r.Unread())`,
|
||||
inputFlags(c, log, map[string]*bool{"Date separators": &d.dated}, "Date separators")
|
||||
chatmsgControls(c, log, d)
|
||||
ui.Row(c).Children(func() {
|
||||
if mujica.Button(c, "Load 100,000", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() {
|
||||
if input.Button(c, "Load 100,000", input.ButtonOptions{Variant: input.Secondary}).Clicked() {
|
||||
for len(d.ids) < 100000 {
|
||||
d.add()
|
||||
}
|
||||
@@ -146,77 +149,77 @@ fmt.Println("unread", r.Unread())`,
|
||||
})
|
||||
})
|
||||
inputSection(c, "Live", func() {
|
||||
opts := mujica.MessageListOptions{ID: func(i int) string { return d.ids[i] }, Label: func(i int) string { return d.texts[i] }}
|
||||
opts := chat.MessageListOptions{ID: func(i int) string { return d.ids[i] }, Label: func(i int) string { return d.texts[i] }}
|
||||
if d.dated {
|
||||
opts.Date = d.day
|
||||
}
|
||||
ui.Column(c).Height(360).Border(1, mujica.Tokens(c).Border).Children(func() {
|
||||
r := mujica.MessageList(c, &d.list, len(d.ids), opts, func(i int) { d.row(c, i) })
|
||||
ui.Column(c).Height(360).Border(1, core.Tokens(c).Border).Children(func() {
|
||||
r := chat.MessageList(c, &d.list, len(d.ids), opts, func(i int) { d.row(c, i) })
|
||||
ui.Text(c, fmt.Sprintf("%d messages, %d unread, at end %v", len(d.ids), r.Unread(), d.list.AtEnd())).Padding(8)
|
||||
})
|
||||
})
|
||||
}},
|
||||
{ID: "203", Name: "MessageBubble", ZhName: "消息气泡", Category: chatmsgCategory,
|
||||
Keys: "气泡不获取焦点;内容中的链接与按钮按 Tab 顺序访问。",
|
||||
Code: `mujica.MessageBubble(c, mujica.MessageAssistant, mujica.MessageBubbleOptions{Name: "Herald"}, func() {
|
||||
Code: `chat.MessageBubble(c, chat.MessageAssistant, chat.MessageBubbleOptions{Name: "Herald"}, func() {
|
||||
ui.Text(c, "The ball begins at nine.")
|
||||
})`,
|
||||
Demo: func(c *ui.Context, log func(string)) {
|
||||
type state struct {
|
||||
role mujica.MessageRole
|
||||
role chat.MessageRole
|
||||
avatar, named bool
|
||||
width float64
|
||||
}
|
||||
s := ui.Local(c.Root(), "203", func() state { return state{role: mujica.MessageAssistant, avatar: true, named: true, width: 360} })
|
||||
roles := []mujica.RadioItem[mujica.MessageRole]{{Value: mujica.MessageUser, Label: "User"}, {Value: mujica.MessageAssistant, Label: "Assistant"},
|
||||
{Value: mujica.MessageSystem, Label: "System"}, {Value: mujica.MessageError, Label: "Error"}}
|
||||
s := ui.Local(c.Root(), "203", func() state { return state{role: chat.MessageAssistant, avatar: true, named: true, width: 360} })
|
||||
roles := []input.RadioItem[chat.MessageRole]{{Value: chat.MessageUser, Label: "User"}, {Value: chat.MessageAssistant, Label: "Assistant"},
|
||||
{Value: chat.MessageSystem, Label: "System"}, {Value: chat.MessageError, Label: "Error"}}
|
||||
inputSection(c, "Parameters", func() {
|
||||
if mujica.RadioGroup(c, &s.role, roles, mujica.RadioGroupOptions{Horizontal: true, Label: "Role"}).Changed() {
|
||||
if input.RadioGroup(c, &s.role, roles, input.RadioGroupOptions{Horizontal: true, Label: "Role"}).Changed() {
|
||||
log(fmt.Sprintf("role %d", s.role))
|
||||
}
|
||||
inputFlags(c, log, map[string]*bool{"Avatar": &s.avatar, "Name": &s.named}, "Avatar", "Name")
|
||||
if mujica.NumberInput(c, &s.width, mujica.NumberInputOptions{Min: 160, Max: 640, Step: 40, Label: "MaxWidth"}).Changed() {
|
||||
if input.NumberInput(c, &s.width, input.NumberInputOptions{Min: 160, Max: 640, Step: 40, Label: "MaxWidth"}).Changed() {
|
||||
log(fmt.Sprintf("MaxWidth %v", s.width))
|
||||
}
|
||||
})
|
||||
inputSection(c, "Live", func() {
|
||||
opts := mujica.MessageBubbleOptions{MaxWidth: float32(s.width)}
|
||||
opts := chat.MessageBubbleOptions{MaxWidth: float32(s.width)}
|
||||
if s.named {
|
||||
opts.Name = "Herald"
|
||||
}
|
||||
if s.avatar {
|
||||
opts.Avatar = func() { mujica.Avatar(c, "Herald", mujica.AvatarOptions{}) }
|
||||
opts.Avatar = func() { display.Avatar(c, "Herald", display.AvatarOptions{}) }
|
||||
}
|
||||
mujica.MessageBubble(c, s.role, opts, func() { ui.Text(c, chatmsgReplies[0]+" "+chatmsgReplies[2]) })
|
||||
chat.MessageBubble(c, s.role, opts, func() { ui.Text(c, chatmsgReplies[0]+" "+chatmsgReplies[2]) })
|
||||
})
|
||||
inputSection(c, "States", func() {
|
||||
for _, r := range roles {
|
||||
mujica.MessageBubble(c, r.Value, mujica.MessageBubbleOptions{Name: r.Label}, func() { ui.Text(c, r.Label+" message") })
|
||||
chat.MessageBubble(c, r.Value, chat.MessageBubbleOptions{Name: r.Label}, func() { ui.Text(c, r.Label+" message") })
|
||||
}
|
||||
})
|
||||
}},
|
||||
{ID: "204", Name: "MessageHeader", ZhName: "消息头", Category: chatmsgCategory, Keys: "不获取焦点。",
|
||||
Code: `mujica.MessageHeader(c, mujica.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: mujica.MessageSent})`,
|
||||
Code: `chat.MessageHeader(c, chat.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: chat.MessageSent})`,
|
||||
Demo: func(c *ui.Context, log func(string)) {
|
||||
status := ui.Local(c.Root(), "204", func() mujica.MessageStatus { return mujica.MessageSent })
|
||||
items := []mujica.RadioItem[mujica.MessageStatus]{{Value: mujica.MessageNoStatus, Label: "None"}, {Value: mujica.MessageSending, Label: "Sending"},
|
||||
{Value: mujica.MessageStreaming, Label: "Streaming"}, {Value: mujica.MessageSent, Label: "Sent"}, {Value: mujica.MessageFailed, Label: "Failed"}}
|
||||
status := ui.Local(c.Root(), "204", func() chat.MessageStatus { return chat.MessageSent })
|
||||
items := []input.RadioItem[chat.MessageStatus]{{Value: chat.MessageNoStatus, Label: "None"}, {Value: chat.MessageSending, Label: "Sending"},
|
||||
{Value: chat.MessageStreaming, Label: "Streaming"}, {Value: chat.MessageSent, Label: "Sent"}, {Value: chat.MessageFailed, Label: "Failed"}}
|
||||
inputSection(c, "Parameters", func() {
|
||||
if mujica.RadioGroup(c, status, items, mujica.RadioGroupOptions{Horizontal: true, Label: "Status"}).Changed() {
|
||||
if input.RadioGroup(c, status, items, input.RadioGroupOptions{Horizontal: true, Label: "Status"}).Changed() {
|
||||
log(fmt.Sprintf("status %d", *status))
|
||||
}
|
||||
})
|
||||
inputSection(c, "Live", func() {
|
||||
mujica.MessageHeader(c, mujica.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: *status})
|
||||
chat.MessageHeader(c, chat.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: *status})
|
||||
})
|
||||
inputSection(c, "States", func() {
|
||||
for _, it := range items[1:] {
|
||||
mujica.MessageHeader(c, mujica.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: it.Value})
|
||||
chat.MessageHeader(c, chat.MessageHeaderOptions{Model: "herald-2", Time: time.Now(), Status: it.Value})
|
||||
}
|
||||
})
|
||||
}},
|
||||
{ID: "205", Name: "StreamingText", ZhName: "流式文本", Category: chatmsgCategory, Keys: "不获取焦点;减少动画时直接显示全部文本。",
|
||||
Code: `mujica.StreamingText(c, reply, mujica.StreamingTextOptions{Streaming: true, Smooth: true})`,
|
||||
Code: `chat.StreamingText(c, reply, chat.StreamingTextOptions{Streaming: true, Smooth: true})`,
|
||||
Demo: func(c *ui.Context, log func(string)) {
|
||||
type state struct {
|
||||
text string
|
||||
@@ -228,11 +231,11 @@ fmt.Println("unread", r.Unread())`,
|
||||
const full = "By order of the Queen, the ball begins at nine. Guests arrive by the east door, and carriages wait in the lower court until midnight."
|
||||
inputSection(c, "Parameters", func() {
|
||||
inputFlags(c, log, map[string]*bool{"Smooth": &s.smooth, "Streaming cursor": &s.streaming, "Stream": &s.auto}, "Smooth", "Streaming cursor", "Stream")
|
||||
if mujica.NumberInput(c, &s.rate, mujica.NumberInputOptions{Min: 10, Max: 400, Step: 10, Label: "Rate"}).Changed() {
|
||||
if input.NumberInput(c, &s.rate, input.NumberInputOptions{Min: 10, Max: 400, Step: 10, Label: "Rate"}).Changed() {
|
||||
log(fmt.Sprintf("Rate %v", s.rate))
|
||||
}
|
||||
ui.Row(c).Children(func() {
|
||||
if mujica.Button(c, "Restart", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() {
|
||||
if input.Button(c, "Restart", input.ButtonOptions{Variant: input.Secondary}).Clicked() {
|
||||
s.text = ""
|
||||
log("stream restarted")
|
||||
}
|
||||
@@ -255,7 +258,7 @@ fmt.Println("unread", r.Unread())`,
|
||||
c.After(150 * time.Millisecond)
|
||||
}
|
||||
inputSection(c, "Live", func() {
|
||||
mujica.StreamingText(c, s.text, mujica.StreamingTextOptions{Streaming: s.streaming && len(s.text) < len(full), Smooth: s.smooth, Rate: s.rate})
|
||||
chat.StreamingText(c, s.text, chat.StreamingTextOptions{Streaming: s.streaming && len(s.text) < len(full), Smooth: s.smooth, Rate: s.rate})
|
||||
})
|
||||
}},
|
||||
}
|
||||
Reference in new issue
Block a user