2020-06-07 04:27:28 +00:00
|
|
|
package cozy
|
|
|
|
|
|
|
|
import (
|
2020-06-13 07:29:32 +00:00
|
|
|
"time"
|
|
|
|
|
2020-06-07 04:27:28 +00:00
|
|
|
"github.com/diamondburned/cchat"
|
2020-06-13 07:29:32 +00:00
|
|
|
"github.com/diamondburned/cchat-gtk/internal/humanize"
|
2020-06-07 04:27:28 +00:00
|
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/messages/container"
|
|
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/messages/message"
|
2020-06-13 07:29:32 +00:00
|
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
2020-07-17 00:21:14 +00:00
|
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/rich/labeluri"
|
2021-01-05 02:05:33 +00:00
|
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/rich/parser/markup"
|
|
|
|
"github.com/diamondburned/cchat/text"
|
2020-06-07 04:27:28 +00:00
|
|
|
"github.com/gotk3/gotk3/gtk"
|
|
|
|
)
|
|
|
|
|
|
|
|
type FullMessage struct {
|
2021-03-29 21:46:52 +00:00
|
|
|
*message.State
|
2020-06-07 04:27:28 +00:00
|
|
|
|
|
|
|
// Grid widgets.
|
2020-06-13 07:29:32 +00:00
|
|
|
Avatar *Avatar
|
2020-06-07 04:27:28 +00:00
|
|
|
MainBox *gtk.Box // wraps header and content
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
HeaderLabel *labeluri.Label
|
|
|
|
timestamp string // markup
|
2020-06-07 04:27:28 +00:00
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
// unwrap is used to removing label handlers.
|
|
|
|
unwrap func()
|
2020-06-13 07:29:32 +00:00
|
|
|
}
|
|
|
|
|
2020-06-07 04:27:28 +00:00
|
|
|
var (
|
2021-01-02 09:24:14 +00:00
|
|
|
_ message.Container = (*FullMessage)(nil)
|
|
|
|
_ container.MessageRow = (*FullMessage)(nil)
|
2020-06-07 04:27:28 +00:00
|
|
|
)
|
|
|
|
|
2020-07-17 00:21:14 +00:00
|
|
|
var avatarCSS = primitives.PrepareClassCSS("cozy-avatar", `
|
2021-05-01 07:26:17 +00:00
|
|
|
.cozy-avatar {
|
|
|
|
margin-top: 2px;
|
|
|
|
}
|
|
|
|
|
2020-07-17 00:21:14 +00:00
|
|
|
/* Slightly dip down on click */
|
|
|
|
.cozy-avatar:active {
|
|
|
|
margin-top: 1px;
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
var mainCSS = primitives.PrepareClassCSS("cozy-main", `
|
|
|
|
.cozy-main {
|
|
|
|
margin-top: 4px;
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
2020-06-07 04:27:28 +00:00
|
|
|
func NewFullMessage(msg cchat.MessageCreate) *FullMessage {
|
2021-03-29 21:46:52 +00:00
|
|
|
return WrapFullMessage(message.NewState(msg))
|
2020-06-07 04:27:28 +00:00
|
|
|
}
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
func WrapFullMessage(gc *message.State) *FullMessage {
|
2021-01-05 02:05:33 +00:00
|
|
|
header := labeluri.NewLabel(text.Rich{})
|
|
|
|
header.SetHAlign(gtk.ALIGN_START) // left-align
|
|
|
|
header.SetMaxWidthChars(100)
|
|
|
|
header.Show()
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
avatar := NewAvatar(gc.Row)
|
2020-06-07 04:27:28 +00:00
|
|
|
avatar.SetMarginStart(container.ColumnSpacing * 2)
|
2020-12-30 06:30:41 +00:00
|
|
|
avatar.Connect("clicked", func(w gtk.IWidget) {
|
2021-01-05 02:05:33 +00:00
|
|
|
if output := header.Output(); len(output.Mentions) > 0 {
|
2020-12-30 06:30:41 +00:00
|
|
|
labeluri.PopoverMentioner(w, output.Input, output.Mentions[0])
|
2020-07-17 00:21:14 +00:00
|
|
|
}
|
|
|
|
})
|
2021-01-02 09:24:14 +00:00
|
|
|
avatar.Show()
|
2020-06-13 07:29:32 +00:00
|
|
|
|
2020-07-17 00:21:14 +00:00
|
|
|
// Attach the class and CSS for the left avatar.
|
|
|
|
avatarCSS(avatar)
|
2020-06-07 04:27:28 +00:00
|
|
|
|
2020-07-06 00:19:48 +00:00
|
|
|
// Attach the username style provider.
|
2021-01-05 02:05:33 +00:00
|
|
|
// primitives.AttachCSS(gc.Username, boldCSS)
|
2020-06-07 04:27:28 +00:00
|
|
|
|
|
|
|
main, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
|
|
|
|
main.PackStart(header, false, false, 0)
|
2020-06-26 04:11:31 +00:00
|
|
|
main.PackStart(gc.Content, false, false, 0)
|
2020-06-07 04:27:28 +00:00
|
|
|
main.SetMarginEnd(container.ColumnSpacing * 2)
|
2021-01-02 09:24:14 +00:00
|
|
|
main.SetMarginStart(container.ColumnSpacing)
|
2020-06-07 04:27:28 +00:00
|
|
|
main.Show()
|
|
|
|
|
2020-06-13 07:29:32 +00:00
|
|
|
// Also attach a class for the main box shown on the right.
|
|
|
|
primitives.AddClass(main, "cozy-main")
|
|
|
|
|
2021-01-02 09:24:14 +00:00
|
|
|
gc.PackStart(avatar, false, false, 0)
|
|
|
|
gc.PackStart(main, true, true, 0)
|
|
|
|
gc.SetClass("cozy-full")
|
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
removeUpdate := gc.Author.Name.OnUpdate(func() {
|
|
|
|
avatar.SetImage(gc.Author.Name.Image())
|
|
|
|
header.SetLabel(gc.Author.Name.Label())
|
|
|
|
})
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
msg := &FullMessage{
|
|
|
|
State: gc,
|
|
|
|
timestamp: formatLongTime(gc.Time),
|
2020-08-20 23:53:13 +00:00
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
Avatar: avatar,
|
|
|
|
MainBox: main,
|
|
|
|
HeaderLabel: header,
|
2020-08-20 23:53:13 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
unwrap: func() { removeUpdate() },
|
2021-03-29 21:46:52 +00:00
|
|
|
}
|
2020-06-13 07:29:32 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
cfg := markup.RenderConfig{}
|
|
|
|
cfg.NoReferencing = true
|
|
|
|
cfg.SetForegroundAnchor(gc.ContentBodyStyle)
|
2021-01-05 02:05:33 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
header.SetRenderer(func(rich text.Rich) markup.RenderOutput {
|
2021-03-29 21:46:52 +00:00
|
|
|
output := markup.RenderCmplxWithConfig(rich, cfg)
|
|
|
|
output.Markup = `<span font_weight="600">` + output.Markup + "</span>"
|
|
|
|
output.Markup += msg.timestamp
|
2021-01-05 02:05:33 +00:00
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
return output
|
|
|
|
})
|
2020-06-13 07:29:32 +00:00
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
return msg
|
2020-06-07 04:27:28 +00:00
|
|
|
}
|
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
func (m *FullMessage) Revert() *message.State {
|
|
|
|
// Remove the handlers.
|
|
|
|
m.unwrap()
|
2021-01-05 02:05:33 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
// Destroy the bottom leaf widgets first.
|
|
|
|
m.Avatar.Destroy()
|
|
|
|
m.HeaderLabel.Destroy()
|
2021-01-05 02:05:33 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
// Remove the content label from main then destroy it, in case destroying it
|
|
|
|
// ruins the label.
|
|
|
|
m.MainBox.Remove(m.Content)
|
|
|
|
m.MainBox.Destroy()
|
2021-01-05 02:05:33 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
m.ClearBox()
|
2020-06-07 04:27:28 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
return m.Unwrap()
|
2021-03-29 21:46:52 +00:00
|
|
|
}
|
2020-06-13 07:29:32 +00:00
|
|
|
|
2021-05-01 07:26:17 +00:00
|
|
|
type full interface{ full() }
|
|
|
|
|
|
|
|
func (m *FullMessage) full() {}
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
func formatLongTime(t time.Time) string {
|
2021-05-01 07:26:17 +00:00
|
|
|
return ` <span alpha="70%" size="small">` + humanize.TimeAgoLong(t) + `</span>`
|
2020-06-13 07:29:32 +00:00
|
|
|
}
|
|
|
|
|
2020-06-07 04:27:28 +00:00
|
|
|
type FullSendingMessage struct {
|
2021-03-29 21:46:52 +00:00
|
|
|
*FullMessage
|
|
|
|
message.Presender
|
2020-06-07 04:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
2021-01-02 09:24:14 +00:00
|
|
|
_ message.Container = (*FullSendingMessage)(nil)
|
|
|
|
_ container.MessageRow = (*FullSendingMessage)(nil)
|
2020-06-07 04:27:28 +00:00
|
|
|
)
|
|
|
|
|
2021-03-29 21:46:52 +00:00
|
|
|
func WrapFullSendingMessage(pstate *message.PresendState) *FullSendingMessage {
|
2020-06-07 04:27:28 +00:00
|
|
|
return &FullSendingMessage{
|
2021-03-29 21:46:52 +00:00
|
|
|
FullMessage: WrapFullMessage(pstate.State),
|
|
|
|
Presender: pstate,
|
2020-06-07 07:06:13 +00:00
|
|
|
}
|
|
|
|
}
|