Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
diamondburned
GitHub Repository: diamondburned/gtkcord4
Path: blob/main/internal/window/quickswitcher/items.go
366 views
1
package quickswitcher
2
3
import (
4
"context"
5
6
"github.com/diamondburned/arikawa/v3/discord"
7
"github.com/diamondburned/gotk4/pkg/gtk/v4"
8
"github.com/diamondburned/gotk4/pkg/pango"
9
"github.com/diamondburned/gotkit/components/onlineimage"
10
"github.com/diamondburned/gotkit/gtkutil/cssutil"
11
"github.com/diamondburned/gotkit/gtkutil/imgutil"
12
"libdb.so/dissent/internal/gtkcord"
13
"libdb.so/dissent/internal/sidebar/channels"
14
)
15
16
type indexItem interface {
17
Row(context.Context) *gtk.ListBoxRow
18
String() string
19
}
20
21
type indexItems []indexItem
22
23
func (its indexItems) String(i int) string { return its[i].String() }
24
func (its indexItems) Len() int { return len(its) }
25
26
type channelItem struct {
27
*discord.Channel
28
guild *discord.Guild
29
name string
30
search string
31
}
32
33
// TODO: move this to gtkcord
34
var threadTypes = map[discord.ChannelType]bool{
35
discord.GuildAnnouncementThread: true,
36
discord.GuildPublicThread: true,
37
discord.GuildPrivateThread: true,
38
}
39
40
var voiceTypes = map[discord.ChannelType]bool{
41
discord.GuildVoice: true,
42
discord.GuildStageVoice: true,
43
}
44
45
func newChannelItem(state *gtkcord.State, guild *discord.Guild, ch *discord.Channel) channelItem {
46
item := channelItem{
47
Channel: ch,
48
guild: guild,
49
}
50
51
if ch.Name != "" {
52
item.name = ch.Name
53
} else {
54
item.name = gtkcord.RecipientNames(ch)
55
}
56
57
if threadTypes[ch.Type] {
58
parent, _ := state.Cabinet.Channel(ch.ParentID)
59
if parent != nil {
60
item.name = parent.Name + " › #" + item.name
61
}
62
}
63
64
if item.guild != nil {
65
item.search = item.guild.Name + " " + item.name
66
} else {
67
item.search = item.name
68
}
69
70
return item
71
}
72
73
func (it channelItem) String() string { return it.search }
74
75
var channelCSS = cssutil.Applier("quickswitcher-channel", `
76
.quickswitcher-channel-icon {
77
margin: 2px 8px;
78
min-width: {$inline_emoji_size};
79
min-height: {$inline_emoji_size};
80
}
81
.quickswitcher-channel-hash {
82
padding: 0px;
83
}
84
.quickswitcher-channel-image {
85
margin-right: 12px;
86
}
87
.quickswitcher-channel-guildname {
88
font-size: 0.85em;
89
color: alpha(@theme_fg_color, 0.75);
90
margin: 4px;
91
margin-left: 18px;
92
margin-bottom: calc(4px - 0.1em);
93
}
94
`)
95
96
func (it channelItem) Row(ctx context.Context) *gtk.ListBoxRow {
97
tooltip := it.name
98
if it.guild != nil {
99
tooltip += " (" + it.guild.Name + ")"
100
}
101
102
box := gtk.NewBox(gtk.OrientationHorizontal, 0)
103
104
row := gtk.NewListBoxRow()
105
row.SetTooltipText(tooltip)
106
row.SetChild(box)
107
channelCSS(row)
108
109
switch it.Type {
110
case discord.DirectMessage, discord.GroupDM:
111
icon := onlineimage.NewAvatar(ctx, imgutil.HTTPProvider, gtkcord.InlineEmojiSize)
112
icon.AddCSSClass("quickswitcher-channel-icon")
113
icon.AddCSSClass("quickswitcher-channel-image")
114
icon.SetHAlign(gtk.AlignCenter)
115
icon.SetText(it.name)
116
if len(it.DMRecipients) == 1 {
117
icon.SetFromURL(gtkcord.InjectAvatarSize(it.DMRecipients[0].AvatarURL()))
118
}
119
120
anim := icon.EnableAnimation()
121
anim.ConnectMotion(row) // TODO: I wonder if this causes memory leaks.
122
123
box.Append(icon)
124
default:
125
icon := channels.NewChannelIcon(it.Channel, func(t discord.ChannelType) (string, bool) {
126
_, isThread := threadTypes[t]
127
return "thread-branch-symbolic", isThread
128
})
129
130
icon.AddCSSClass("quickswitcher-channel-icon")
131
icon.AddCSSClass("quickswitcher-channel-hash")
132
icon.SetHAlign(gtk.AlignCenter)
133
134
box.Append(icon)
135
}
136
137
name := gtk.NewLabel(it.name)
138
name.AddCSSClass("quickswitcher-channel-name")
139
name.SetHExpand(true)
140
name.SetXAlign(0)
141
name.SetEllipsize(pango.EllipsizeEnd)
142
143
box.Append(name)
144
145
if it.guild != nil {
146
guildName := gtk.NewLabel(it.guild.Name)
147
guildName.AddCSSClass("quickswitcher-channel-guildname")
148
guildName.SetEllipsize(pango.EllipsizeEnd)
149
150
box.Append(guildName)
151
}
152
153
return row
154
}
155
156
type guildItem struct {
157
*discord.Guild
158
}
159
160
func newGuildItem(guild *discord.Guild) guildItem {
161
return guildItem{
162
Guild: guild,
163
}
164
}
165
166
func (it guildItem) String() string { return it.Name }
167
168
var guildCSS = cssutil.Applier("quickswitcher-guild", `
169
.quickswitcher-guild-icon {
170
margin: 2px 8px;
171
min-width: {$inline_emoji_size};
172
min-height: {$inline_emoji_size};
173
}
174
`)
175
176
func (it guildItem) Row(ctx context.Context) *gtk.ListBoxRow {
177
row := gtk.NewListBoxRow()
178
guildCSS(row)
179
180
icon := onlineimage.NewAvatar(ctx, imgutil.HTTPProvider, gtkcord.InlineEmojiSize)
181
icon.AddCSSClass("quickswitcher-guild-icon")
182
icon.SetText(it.Name)
183
icon.SetFromURL(it.IconURL())
184
icon.SetHAlign(gtk.AlignCenter)
185
186
anim := icon.EnableAnimation()
187
anim.ConnectMotion(row)
188
189
name := gtk.NewLabel(it.Name)
190
name.AddCSSClass("quickswitcher-guild-name")
191
name.SetHExpand(true)
192
name.SetXAlign(0)
193
194
box := gtk.NewBox(gtk.OrientationHorizontal, 0)
195
box.Append(icon)
196
box.Append(name)
197
198
row.SetChild(box)
199
return row
200
}
201
202