Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
diamondburned
GitHub Repository: diamondburned/gtkcord4
Path: blob/main/internal/sidebar/guilds/guild.go
366 views
1
package guilds
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/gotkit/gtkutil/cssutil"
9
"github.com/diamondburned/ningen/v3"
10
"libdb.so/dissent/internal/components/hoverpopover"
11
"libdb.so/dissent/internal/gtkcord"
12
"libdb.so/dissent/internal/sidebar/sidebutton"
13
)
14
15
// Guild is a widget showing a single guild icon.
16
type Guild struct {
17
*sidebutton.Button
18
ctx context.Context
19
parent *Folder
20
popover *hoverpopover.MarkupHoverPopover
21
id discord.GuildID
22
name string
23
}
24
25
var guildCSS = cssutil.Applier("guild-guild", `
26
.guild-name {
27
font-weight: bold;
28
}
29
`)
30
31
func NewGuild(ctx context.Context, id discord.GuildID) *Guild {
32
g := &Guild{ctx: ctx, id: id}
33
g.Button = sidebutton.NewButton(ctx, func() {
34
parent := gtk.BaseWidget(g.Button.Parent())
35
parent.ActivateAction("win.open-guild", gtkcord.NewGuildIDVariant(id))
36
})
37
38
g.popover = hoverpopover.NewMarkupHoverPopover(g.Button, func(w *hoverpopover.MarkupHoverPopoverWidget) bool {
39
w.AddCSSClass("guild-name-popover")
40
w.SetPosition(gtk.PosRight)
41
w.Label.AddCSSClass("guild-name")
42
w.Label.SetText(g.name)
43
return true
44
})
45
46
g.SetUnavailable()
47
guildCSS(g)
48
return g
49
}
50
51
// ID returns the guild ID.
52
func (g *Guild) ID() discord.GuildID { return g.id }
53
54
// Name returns the guild's name.
55
func (g *Guild) Name() string { return g.name }
56
57
// Invalidate invalidates and updates the state of the guild.
58
func (g *Guild) Invalidate() {
59
state := gtkcord.FromContext(g.ctx)
60
61
guild, err := state.Cabinet.Guild(g.id)
62
if err != nil {
63
g.SetUnavailable()
64
return
65
}
66
67
g.Update(guild)
68
}
69
70
// SetUnavailable sets the guild as unavailable. It stays unavailable until
71
// either Invalidate sees it or Update is called on it.
72
func (g *Guild) SetUnavailable() {
73
g.name = "(guild unavailable)"
74
g.Icon.SetIconName("dialog-question-symbolic")
75
g.Icon.SetText("")
76
g.SetSensitive(false)
77
}
78
79
// Update updates the guild with the given Discord object.
80
func (g *Guild) Update(guild *discord.Guild) {
81
g.name = guild.Name
82
83
g.SetSensitive(true)
84
g.Icon.SetText(guild.Name)
85
g.Icon.SetFromURL(gtkcord.InjectAvatarSize(guild.IconURL()))
86
87
g.InvalidateUnread()
88
}
89
90
// SetParentFolder sets the parent guild folder.
91
func (g *Guild) SetParentFolder(parent *Folder) {
92
g.parent = parent
93
}
94
95
// ParentFolder returns the guild's parent folder.
96
func (g *Guild) ParentFolder() *Folder {
97
return g.parent
98
}
99
100
func (g *Guild) viewChild() {}
101
102
// var channelUnreadTypes = []discord.ChannelType{
103
// discord.GuildText,
104
// discord.GuildPublicThread,
105
// discord.GuildPrivateThread,
106
// }
107
108
// InvalidateUnread invalidates the guild's unread state.
109
func (g *Guild) InvalidateUnread() {
110
state := gtkcord.FromContext(g.ctx)
111
112
var mentions int
113
114
chs, _ := state.Cabinet.Channels(g.id)
115
for _, ch := range chs {
116
read := state.ReadState.ReadState(ch.ID)
117
if read != nil {
118
mentions += read.MentionCount
119
}
120
}
121
122
g.SetIndicator(state.GuildIsUnread(g.id, ningen.GuildUnreadOpts{
123
UnreadOpts: ningen.UnreadOpts{},
124
Types: gtkcord.AllowedChannelTypes,
125
}))
126
g.Mentions.SetCount(mentions)
127
128
if g.parent != nil {
129
g.parent.InvalidateUnread()
130
}
131
}
132
133