Skip to content

Commit

Permalink
initial stages stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
ouwou committed Mar 12, 2024
1 parent b3a8356 commit 98218df
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 32 deletions.
12 changes: 9 additions & 3 deletions src/components/channellist/cellrendererchannels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &m
return get_preferred_width_vfunc_thread(widget, minimum_width, natural_width);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
case RenderType::VoiceStage:
return get_preferred_width_vfunc_voice_channel(widget, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_vfunc_voice_participant(widget, minimum_width, natural_width);
Expand All @@ -147,6 +148,7 @@ void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &wid
return get_preferred_width_for_height_vfunc_thread(widget, height, minimum_width, natural_width);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
case RenderType::VoiceStage:
return get_preferred_width_for_height_vfunc_voice_channel(widget, height, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_for_height_vfunc_voice_participant(widget, height, minimum_width, natural_width);
Expand All @@ -172,6 +174,7 @@ void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &
return get_preferred_height_vfunc_thread(widget, minimum_height, natural_height);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
case RenderType::VoiceStage:
return get_preferred_height_vfunc_voice_channel(widget, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_vfunc_voice_participant(widget, minimum_height, natural_height);
Expand All @@ -197,6 +200,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &wid
return get_preferred_height_for_width_vfunc_thread(widget, width, minimum_height, natural_height);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
case RenderType::VoiceStage:
return get_preferred_height_for_width_vfunc_voice_channel(widget, width, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_for_width_vfunc_voice_participant(widget, width, minimum_height, natural_height);
Expand All @@ -222,7 +226,9 @@ void CellRendererChannels::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr,
return render_vfunc_thread(cr, widget, background_area, cell_area, flags);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags);
return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags, "\U0001F50A");
case RenderType::VoiceStage:
return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags, "\U0001F4E1");
case RenderType::VoiceParticipant:
return render_vfunc_voice_participant(cr, widget, background_area, cell_area, flags);
#endif
Expand Down Expand Up @@ -581,7 +587,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_voice_channel(Gt
m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height);
}

void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags, const char *emoji) {
// channel name text
Gtk::Requisition minimum_size, natural_size;
m_renderer_text.get_preferred_size(widget, minimum_size, natural_size);
Expand All @@ -598,7 +604,7 @@ void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo:
Pango::FontDescription font;
font.set_family("sans 14");

auto layout = widget.create_pango_layout("\U0001F50A");
auto layout = widget.create_pango_layout(emoji);
layout->set_font_description(font);
layout->set_alignment(Pango::ALIGN_LEFT);
cr->set_source_rgba(1.0, 1.0, 1.0, 1.0);
Expand Down
4 changes: 3 additions & 1 deletion src/components/channellist/cellrendererchannels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum class RenderType : uint8_t {
// TODO: maybe enable anyways but without ability to join if no voice support
#ifdef WITH_VOICE
VoiceChannel,
VoiceStage, // identical to non-stage except for icon
VoiceParticipant,
#endif

Expand Down Expand Up @@ -117,7 +118,8 @@ class CellRendererChannels : public Gtk::CellRenderer {
Gtk::Widget &widget,
const Gdk::Rectangle &background_area,
const Gdk::Rectangle &cell_area,
Gtk::CellRendererState flags);
Gtk::CellRendererState flags,
const char *emoji);

// voice participant
void get_preferred_width_vfunc_voice_participant(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;
Expand Down
52 changes: 47 additions & 5 deletions src/components/channellist/channellisttree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ ChannelListTree::ChannelListTree()
#ifdef WITH_VOICE
, m_menu_voice_channel_join("_Join", true)
, m_menu_voice_channel_disconnect("_Disconnect", true)
, m_menu_voice_stage_join("_Join", true)
, m_menu_voice_stage_disconnect("_Disconnect", true)
#endif
, m_menu_dm_copy_id("_Copy ID", true)
, m_menu_dm_close("") // changes depending on if group or not
Expand Down Expand Up @@ -212,6 +214,19 @@ ChannelListTree::ChannelListTree()
m_menu_voice_channel.append(m_menu_voice_channel_join);
m_menu_voice_channel.append(m_menu_voice_channel_disconnect);
m_menu_voice_channel.show_all();

m_menu_voice_stage_join.signal_activate().connect([this]() {
const auto id = static_cast<Snowflake>((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]);
m_signal_action_join_voice_channel.emit(id);
});

m_menu_voice_stage_disconnect.signal_activate().connect([this]() {
m_signal_action_disconnect_voice.emit();
});

m_menu_voice_stage.append(m_menu_voice_stage_join);
m_menu_voice_stage.append(m_menu_voice_stage_disconnect);
m_menu_voice_stage.show_all();
#endif

m_menu_dm_copy_id.signal_activate().connect([this] {
Expand Down Expand Up @@ -356,8 +371,8 @@ int ChannelListTree::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::Tree
if (a_type == RenderType::DMHeader) return -1;
if (b_type == RenderType::DMHeader) return 1;
#ifdef WITH_VOICE
if (a_type == RenderType::TextChannel && b_type == RenderType::VoiceChannel) return -1;
if (b_type == RenderType::TextChannel && a_type == RenderType::VoiceChannel) return 1;
if (a_type == RenderType::TextChannel && (b_type == RenderType::VoiceChannel || b_type == RenderType::VoiceStage)) return -1;
if (b_type == RenderType::TextChannel && (a_type == RenderType::VoiceChannel || a_type == RenderType::VoiceStage)) return 1;
#endif
return static_cast<int>(std::clamp(a_sort - b_sort, int64_t(-1), int64_t(1)));
}
Expand Down Expand Up @@ -624,6 +639,7 @@ void ChannelListTree::OnThreadListSync(const ThreadListSyncData &data) {
#ifdef WITH_VOICE
void ChannelListTree::OnVoiceUserConnect(Snowflake user_id, Snowflake channel_id) {
auto parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::VoiceChannel);
if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::VoiceStage);
if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::DM);
if (!parent_iter) return;
const auto user = Abaddon::Get().GetDiscordClient().GetUser(user_id);
Expand Down Expand Up @@ -906,7 +922,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
const auto channel = discord.GetChannel(channel_.ID);
if (!channel.has_value()) continue;
#ifdef WITH_VOICE
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE) {
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE || channel->Type == ChannelType::GUILD_STAGE_VOICE) {
#else
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS) {
#endif
Expand Down Expand Up @@ -953,10 +969,14 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
}
#ifdef WITH_VOICE
else {
else if (channel.Type == ChannelType::GUILD_VOICE) {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
} else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
channel_row[m_columns.m_type] = RenderType::VoiceStage;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
}
#endif
channel_row[m_columns.m_id] = channel.ID;
Expand Down Expand Up @@ -985,10 +1005,14 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
}
#ifdef WITH_VOICE
else {
else if (channel.Type == ChannelType::GUILD_VOICE) {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
} else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
channel_row[m_columns.m_type] = RenderType::VoiceStage;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
}
#endif
channel_row[m_columns.m_id] = channel.ID;
Expand Down Expand Up @@ -1333,6 +1357,10 @@ bool ChannelListTree::OnButtonPressEvent(GdkEventButton *ev) {
OnVoiceChannelSubmenuPopup();
m_menu_voice_channel.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
break;
case RenderType::VoiceStage:
OnVoiceStageSubmenuPopup();
m_menu_voice_stage.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
break;
#endif
case RenderType::DM: {
OnDMSubmenuPopup();
Expand Down Expand Up @@ -1440,6 +1468,20 @@ void ChannelListTree::OnVoiceChannelSubmenuPopup() {
m_menu_voice_channel_disconnect.set_sensitive(false);
}
}

void ChannelListTree::OnVoiceStageSubmenuPopup() {
const auto iter = m_model->get_iter(m_path_for_menu);
if (!iter) return;
const auto id = static_cast<Snowflake>((*iter)[m_columns.m_id]);
auto &discord = Abaddon::Get().GetDiscordClient();
if (discord.IsVoiceConnected() || discord.IsVoiceConnecting()) {
m_menu_voice_stage_join.set_sensitive(false);
m_menu_voice_stage_disconnect.set_sensitive(discord.GetVoiceChannelID() == id);
} else {
m_menu_voice_stage_join.set_sensitive(true);
m_menu_voice_stage_disconnect.set_sensitive(false);
}
}
#endif

void ChannelListTree::OnDMSubmenuPopup() {
Expand Down
5 changes: 5 additions & 0 deletions src/components/channellist/channellisttree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ class ChannelListTree : public Gtk::ScrolledWindow {
Gtk::Menu m_menu_voice_channel;
Gtk::MenuItem m_menu_voice_channel_join;
Gtk::MenuItem m_menu_voice_channel_disconnect;

Gtk::Menu m_menu_voice_stage;
Gtk::MenuItem m_menu_voice_stage_join;
Gtk::MenuItem m_menu_voice_stage_disconnect;
#endif

Gtk::Menu m_menu_dm;
Expand Down Expand Up @@ -196,6 +200,7 @@ class ChannelListTree : public Gtk::ScrolledWindow {

#ifdef WITH_VOICE
void OnVoiceChannelSubmenuPopup();
void OnVoiceStageSubmenuPopup();
#endif

bool m_updating_listing = false;
Expand Down
16 changes: 0 additions & 16 deletions src/discord/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,6 @@ enum class ChannelType : int {
GUILD_MEDIA = 16,
};

enum class StagePrivacy {
PUBLIC = 1,
GUILD_ONLY = 2,
};

constexpr const char *GetStagePrivacyDisplayString(StagePrivacy e) {
switch (e) {
case StagePrivacy::PUBLIC:
return "Public";
case StagePrivacy::GUILD_ONLY:
return "Guild Only";
default:
return "Unknown";
}
}

// should be moved somewhere?

struct ThreadMetadataData {
Expand Down
47 changes: 47 additions & 0 deletions src/discord/discord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,15 @@ void DiscordClient::HandleGatewayMessage(std::string str) {
case GatewayEvent::GUILD_MEMBERS_CHUNK: {
HandleGatewayGuildMembersChunk(m);
} break;
case GatewayEvent::STAGE_INSTANCE_CREATE: {
HandleGatewayStageInstanceCreate(m);
} break;
case GatewayEvent::STAGE_INSTANCE_UPDATE: {
HandleGatewayStageInstanceUpdate(m);
} break;
case GatewayEvent::STAGE_INSTANCE_DELETE: {
HandleGatewayStageInstanceDelete(m);
} break;
#ifdef WITH_VOICE
case GatewayEvent::VOICE_STATE_UPDATE: {
HandleGatewayVoiceStateUpdate(m);
Expand Down Expand Up @@ -2296,6 +2305,29 @@ void DiscordClient::HandleGatewayGuildMembersChunk(const GatewayMessage &msg) {
m_store.EndTransaction();
}

void DiscordClient::HandleGatewayStageInstanceCreate(const GatewayMessage &msg) {
StageInstance data = msg.Data;
spdlog::get("discord")->debug("STAGE_INSTANCE_CREATE: {} in {}", data.ID, data.ChannelID);
m_stage_instances[data.ID] = data;
m_channel_to_stage_instance[data.ChannelID] = data.ID;
m_signal_stage_instance_create.emit(data);
}

void DiscordClient::HandleGatewayStageInstanceUpdate(const GatewayMessage &msg) {
StageInstance data = msg.Data;
spdlog::get("discord")->debug("STAGE_INSTANCE_UPDATE: {} in {}", data.ID, data.ChannelID);
m_stage_instances[data.ID] = data;
m_signal_stage_instance_update.emit(data);
}

void DiscordClient::HandleGatewayStageInstanceDelete(const GatewayMessage &msg) {
StageInstance data = msg.Data;
spdlog::get("discord")->debug("STAGE_INSTANCE_DELETE: {} in {}", data.ID, data.ChannelID);
m_stage_instances.erase(data.ID);
m_channel_to_stage_instance.erase(data.ChannelID);
m_signal_stage_instance_delete.emit(data);
}

#ifdef WITH_VOICE

/*
Expand Down Expand Up @@ -3001,6 +3033,9 @@ void DiscordClient::LoadEventMap() {
m_event_map["VOICE_STATE_UPDATE"] = GatewayEvent::VOICE_STATE_UPDATE;
m_event_map["VOICE_SERVER_UPDATE"] = GatewayEvent::VOICE_SERVER_UPDATE;
m_event_map["CALL_CREATE"] = GatewayEvent::CALL_CREATE;
m_event_map["STAGE_INSTANCE_CREATE"] = GatewayEvent::STAGE_INSTANCE_CREATE;
m_event_map["STAGE_INSTANCE_UPDATE"] = GatewayEvent::STAGE_INSTANCE_UPDATE;
m_event_map["STAGE_INSTANCE_DELETE"] = GatewayEvent::STAGE_INSTANCE_DELETE;
}

DiscordClient::type_signal_gateway_ready DiscordClient::signal_gateway_ready() {
Expand Down Expand Up @@ -3179,6 +3214,18 @@ DiscordClient::type_signal_guild_members_chunk DiscordClient::signal_guild_membe
return m_signal_guild_members_chunk;
}

DiscordClient::type_signal_stage_instance_create DiscordClient::signal_stage_instance_create() {
return m_signal_stage_instance_create;
}

DiscordClient::type_signal_stage_instance_update DiscordClient::signal_stage_instance_update() {
return m_signal_stage_instance_update;
}

DiscordClient::type_signal_stage_instance_delete DiscordClient::signal_stage_instance_delete() {
return m_signal_stage_instance_delete;
}

DiscordClient::type_signal_added_to_thread DiscordClient::signal_added_to_thread() {
return m_signal_added_to_thread;
}
Expand Down
17 changes: 16 additions & 1 deletion src/discord/discord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,16 @@ class DiscordClient {
void HandleGatewayMessageAck(const GatewayMessage &msg);
void HandleGatewayUserGuildSettingsUpdate(const GatewayMessage &msg);
void HandleGatewayGuildMembersChunk(const GatewayMessage &msg);
void HandleGatewayStageInstanceCreate(const GatewayMessage &msg);
void HandleGatewayStageInstanceUpdate(const GatewayMessage &msg);
void HandleGatewayStageInstanceDelete(const GatewayMessage &msg);
void HandleGatewayReadySupplemental(const GatewayMessage &msg);
void HandleGatewayReconnect(const GatewayMessage &msg);
void HandleGatewayInvalidSession(const GatewayMessage &msg);

#ifdef WITH_VOICE
void HandleGatewayVoiceStateUpdate(const GatewayMessage &msg);
void
HandleGatewayVoiceStateUpdate(const GatewayMessage &msg);
void HandleGatewayVoiceServerUpdate(const GatewayMessage &msg);
void HandleGatewayCallCreate(const GatewayMessage &msg);

Expand Down Expand Up @@ -341,6 +345,8 @@ class DiscordClient {
std::unordered_set<Snowflake> m_muted_channels;
std::unordered_map<Snowflake, int> m_unread;
std::unordered_set<Snowflake> m_channel_muted_parent;
std::map<Snowflake, StageInstance> m_stage_instances;
std::map<Snowflake, Snowflake> m_channel_to_stage_instance;

UserData m_user_data;
UserSettings m_user_settings;
Expand Down Expand Up @@ -441,6 +447,9 @@ class DiscordClient {
typedef sigc::signal<void, ThreadMemberListUpdateData> type_signal_thread_member_list_update;
typedef sigc::signal<void, MessageAckData> type_signal_message_ack;
typedef sigc::signal<void, GuildMembersChunkData> type_signal_guild_members_chunk;
typedef sigc::signal<void, StageInstance> type_signal_stage_instance_create;
typedef sigc::signal<void, StageInstance> type_signal_stage_instance_update;
typedef sigc::signal<void, StageInstance> type_signal_stage_instance_delete;

// not discord dispatch events
typedef sigc::signal<void, Snowflake> type_signal_added_to_thread;
Expand Down Expand Up @@ -513,6 +522,9 @@ class DiscordClient {
type_signal_thread_member_list_update signal_thread_member_list_update();
type_signal_message_ack signal_message_ack();
type_signal_guild_members_chunk signal_guild_members_chunk();
type_signal_stage_instance_create signal_stage_instance_create();
type_signal_stage_instance_update signal_stage_instance_update();
type_signal_stage_instance_delete signal_stage_instance_delete();

type_signal_added_to_thread signal_added_to_thread();
type_signal_removed_from_thread signal_removed_from_thread();
Expand Down Expand Up @@ -582,6 +594,9 @@ class DiscordClient {
type_signal_thread_member_list_update m_signal_thread_member_list_update;
type_signal_message_ack m_signal_message_ack;
type_signal_guild_members_chunk m_signal_guild_members_chunk;
type_signal_stage_instance_create m_signal_stage_instance_create;
type_signal_stage_instance_update m_signal_stage_instance_update;
type_signal_stage_instance_delete m_signal_stage_instance_delete;

type_signal_removed_from_thread m_signal_removed_from_thread;
type_signal_added_to_thread m_signal_added_to_thread;
Expand Down
4 changes: 4 additions & 0 deletions src/discord/objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "auditlog.hpp"
#include "relationship.hpp"
#include "errors.hpp"
#include "stage.hpp"

// most stuff below should just be objects that get processed and thrown away immediately

Expand Down Expand Up @@ -110,6 +111,9 @@ enum class GatewayEvent : int {
VOICE_STATE_UPDATE,
VOICE_SERVER_UPDATE,
CALL_CREATE,
STAGE_INSTANCE_CREATE,
STAGE_INSTANCE_UPDATE,
STAGE_INSTANCE_DELETE,
};

enum class GatewayCloseCode : uint16_t {
Expand Down
Loading

0 comments on commit 98218df

Please sign in to comment.