-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathui_message.go
More file actions
115 lines (99 loc) · 2.8 KB
/
Copy pathui_message.go
File metadata and controls
115 lines (99 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"sync"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
const iconSize = float32(32)
var (
resCache = map[string]fyne.Resource{}
resCacheLock sync.RWMutex
)
type messageCell struct {
widget.BaseWidget
msg *message
}
func newMessageCell(m *message) *messageCell {
ret := &messageCell{msg: m}
ret.ExtendBaseWidget(ret)
return ret
}
func (m *messageCell) avatarResource() fyne.Resource {
if m.msg.user == nil || m.msg.user.avatarURL == "" {
return nil
}
resCacheLock.RLock()
ret, ok := resCache[m.msg.user.avatarURL]
resCacheLock.RUnlock()
if ok {
return ret
}
url, err := storage.ParseURI(m.msg.user.avatarURL)
if err != nil || url == nil {
return nil
}
ret, _ = storage.LoadResourceFromURI(url)
resCacheLock.Lock()
resCache[m.msg.user.avatarURL] = ret
resCacheLock.Unlock()
return ret
}
// func (m *messageCell) setMessage(new *message) {
// m.msg = new
// m.Refresh()
// }
func (m *messageCell) CreateRenderer() fyne.WidgetRenderer {
name := widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{Bold: true})
name.Truncation = fyne.TextTruncateEllipsis
body := widget.NewRichText()
body.Wrapping = fyne.TextWrapWord
return &messageRenderer{m: m,
top: name,
main: body, pic: widget.NewIcon(nil), sep: widget.NewSeparator()}
}
type messageRenderer struct {
m *messageCell
top *widget.Label
main *widget.RichText
pic *widget.Icon
sep *widget.Separator
}
func (m *messageRenderer) Destroy() {
}
func (m *messageRenderer) Layout(s fyne.Size) {
remainWidth := s.Width - iconSize - theme.Padding()*2
remainStart := iconSize + theme.Padding()*2
m.pic.Resize(fyne.NewSize(iconSize, iconSize))
m.pic.Move(fyne.NewPos(theme.Padding(), theme.Padding()))
m.top.Move(fyne.NewPos(remainStart, -theme.Padding()))
m.top.Resize(fyne.NewSize(remainWidth, m.top.MinSize().Height))
m.main.Move(fyne.NewPos(remainStart, m.top.MinSize().Height-theme.Padding()*4))
m.main.Resize(fyne.NewSize(remainWidth, m.main.MinSize().Height))
m.sep.Move(fyne.NewPos(0, s.Height-theme.SeparatorThicknessSize()))
m.sep.Resize(fyne.NewSize(s.Width, theme.SeparatorThicknessSize()))
}
func (m *messageRenderer) MinSize() fyne.Size {
s1 := m.top.MinSize()
s2 := m.main.MinSize()
w := fyne.Max(s1.Width, s2.Width)
return fyne.NewSize(w+iconSize+theme.Padding()*2,
s1.Height+s2.Height-theme.Padding()*4)
}
func (m *messageRenderer) Objects() []fyne.CanvasObject {
return []fyne.CanvasObject{m.top, m.main, m.pic, m.sep}
}
func (m *messageRenderer) Refresh() {
if m.m.msg.user == nil {
m.top.SetText("(Unknown)")
} else {
if m.m.msg.user.name != "" {
m.top.SetText(m.m.msg.user.name)
} else {
m.top.SetText(m.m.msg.user.username)
}
}
m.main.ParseMarkdown(m.m.msg.content)
go m.pic.SetResource(m.m.avatarResource())
}