Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
diamondburned
GitHub Repository: diamondburned/gtkcord4
Path: blob/main/internal/sidebar/channels/channel_icon.go
366 views
1
package channels
2
3
import (
4
"log/slog"
5
6
"github.com/diamondburned/arikawa/v3/discord"
7
"github.com/diamondburned/gotk4/pkg/gtk/v4"
8
"github.com/diamondburned/gotkit/gtkutil/cssutil"
9
)
10
11
var channelIndicatorCSS = cssutil.Applier("channel-item-indicator", `
12
@define-color channel_item_indicator_color @theme_bg_color;
13
14
.channel-item-indicator {
15
font-family: monospace;
16
font-size: 0.75em;
17
font-weight: bold;
18
19
margin-right: -12px;
20
min-width: 12px; /* prevent (size >= 0) warnings */
21
22
/* Replicate a text outline for the indicators. */
23
text-shadow:
24
0 0 2px @channel_item_indicator_color,
25
0 0 2px @channel_item_indicator_color,
26
0 0 2px @channel_item_indicator_color,
27
0 0 2px @channel_item_indicator_color,
28
0 0 2px @channel_item_indicator_color,
29
0 0 2px @channel_item_indicator_color,
30
0 0 2px @channel_item_indicator_color,
31
0 0 2px @channel_item_indicator_color,
32
0 0 2px @channel_item_indicator_color,
33
0 0 2px @channel_item_indicator_color,
34
0 0 2px @channel_item_indicator_color,
35
0 0 2px @channel_item_indicator_color,
36
0 0 2px @channel_item_indicator_color,
37
0 0 2px @channel_item_indicator_color,
38
0 0 2px @channel_item_indicator_color;
39
}
40
`)
41
42
var channelIconImageCSS = cssutil.Applier("channel-icon-image", `
43
.channel-icon-image {
44
min-width: 0px;
45
}
46
`)
47
48
type ChannelIconOverrideFunc func(t discord.ChannelType) (string, bool)
49
50
var _ ChannelIconOverrideFunc = channelIconBase
51
52
func channelIconBase(chType discord.ChannelType) (string, bool) {
53
switch chType {
54
case discord.GuildText:
55
return "channel-symbolic", true
56
case discord.GuildAnnouncement:
57
return "channel-broadcast-symbolic", true
58
case discord.GuildPublicThread, discord.GuildPrivateThread, discord.GuildAnnouncementThread:
59
return "thread-branch-symbolic", true
60
case discord.GuildVoice, discord.GuildStageVoice:
61
return "channel-voice-symbolic", true
62
case discord.DirectMessage:
63
return "person-symbolic", true
64
case discord.GroupDM:
65
return "group-symbolic", true
66
default:
67
return "channel-symbolic", false
68
}
69
}
70
71
// ChannelIcon is a widget that displays a channel's icon.
72
// This does not handle DM channels, as it does not display avatars. It is only
73
// for displaying the channel icon.
74
type ChannelIcon struct {
75
*gtk.Widget
76
Icon *gtk.Image
77
}
78
79
const unknownChannelType discord.ChannelType = 9999
80
81
// NewChannelIcon creates a new ChannelIcon.
82
// If ch is nil, the icon will be a special unknown icon.
83
func NewChannelIcon(ch *discord.Channel, overrides ...ChannelIconOverrideFunc) *ChannelIcon {
84
chType := unknownChannelType
85
var nsfw bool
86
if ch != nil {
87
chType = ch.Type
88
nsfw = ch.NSFW
89
}
90
91
var iconName string
92
var found bool
93
for _, override := range append(overrides, channelIconBase) {
94
iconName, found = override(chType)
95
if found {
96
break
97
}
98
}
99
100
if !found && chType != unknownChannelType {
101
slog.Debug(
102
"channel icon called with unknown channel type, using fallback icon",
103
"channel_type", chType)
104
}
105
106
icon := gtk.NewImageFromIconName(iconName)
107
channelIconImageCSS(icon)
108
109
if found && !nsfw {
110
return &ChannelIcon{
111
Widget: &icon.Widget,
112
Icon: icon,
113
}
114
}
115
116
var indicatorStr string
117
if !found {
118
indicatorStr = "?"
119
} else {
120
indicatorStr = "!"
121
}
122
123
indicator := gtk.NewLabel(indicatorStr)
124
indicator.SetXAlign(1)
125
indicator.SetHAlign(gtk.AlignCenter)
126
indicator.SetVAlign(gtk.AlignEnd)
127
indicator.SetHExpand(false)
128
indicator.SetVExpand(false)
129
channelIndicatorCSS(indicator)
130
131
iconFrame := gtk.NewOverlay()
132
iconFrame.SetHAlign(gtk.AlignCenter)
133
iconFrame.SetVAlign(gtk.AlignCenter)
134
iconFrame.SetChild(icon)
135
iconFrame.AddOverlay(indicator)
136
137
return &ChannelIcon{
138
Widget: &iconFrame.Widget,
139
Icon: icon,
140
}
141
}
142
143