Skip to content

Commit

Permalink
Merge pull request #242 from uowuo/classic-channels
Browse files Browse the repository at this point in the history
Discord-style channel/server listing
  • Loading branch information
ouwou authored Mar 9, 2024
2 parents 91e89c0 + ff76ec5 commit 43f87ae
Show file tree
Hide file tree
Showing 20 changed files with 1,062 additions and 147 deletions.
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,23 +291,25 @@ For example, memory_db would be set by adding `memory_db = true` under the line
#### gui
| Setting | Type | Default | Description |
|-----------------------------|---------|---------|----------------------------------------------------------------------------------------------------------------------------|
| `member_list_discriminator` | boolean | true | show user discriminators in the member list |
| `stock_emojis` | boolean | true | allow abaddon to substitute unicode emojis with images from emojis.bin, must be false to allow GTK to render emojis itself |
| `custom_emojis` | boolean | true | download and use custom Discord emojis |
| `css` | string | | path to the main CSS file |
| `animations` | boolean | true | use animated images where available (e.g. server icons, emojis, avatars). false means static images will be used |
| `animated_guild_hover_only` | boolean | true | only animate guild icons when the guild is being hovered over |
| `owner_crown` | boolean | true | show a crown next to the owner |
| `unreads` | boolean | true | show unread indicators and mention badges |
| `save_state` | boolean | true | save the state of the gui (active channels, tabs, expanded channels) |
| `alt_menu` | boolean | false | keep the menu hidden unless revealed with alt key |
| `hide_to_tray` | boolean | false | hide abaddon to the system tray on window close |
| `show_deleted_indicator` | boolean | true | show \[deleted\] indicator next to deleted messages instead of actually deleting the message |
| `font_scale` | double | | scale font rendering. 1 is unchanged |
| `image_embed_clamp_width` | int | 400 | maximum width of image embeds |
| `image_embed_clamp_height` | int | 300 | maximum height of image embeds |
| Setting | Type | Default | Description |
|--------------------------------|---------|---------|----------------------------------------------------------------------------------------------------------------------------|
| `member_list_discriminator` | boolean | true | show user discriminators in the member list |
| `stock_emojis` | boolean | true | allow abaddon to substitute unicode emojis with images from emojis.bin, must be false to allow GTK to render emojis itself |
| `custom_emojis` | boolean | true | download and use custom Discord emojis |
| `css` | string | | path to the main CSS file |
| `animations` | boolean | true | use animated images where available (e.g. server icons, emojis, avatars). false means static images will be used |
| `animated_guild_hover_only` | boolean | true | only animate guild icons when the guild is being hovered over |
| `owner_crown` | boolean | true | show a crown next to the owner |
| `unreads` | boolean | true | show unread indicators and mention badges |
| `save_state` | boolean | true | save the state of the gui (active channels, tabs, expanded channels) |
| `alt_menu` | boolean | false | keep the menu hidden unless revealed with alt key |
| `hide_to_tray` | boolean | false | hide abaddon to the system tray on window close |
| `show_deleted_indicator` | boolean | true | show \[deleted\] indicator next to deleted messages instead of actually deleting the message |
| `font_scale` | double | | scale font rendering. 1 is unchanged |
| `image_embed_clamp_width` | int | 400 | maximum width of image embeds |
| `image_embed_clamp_height` | int | 300 | maximum height of image embeds |
| `classic_channels` | boolean | false | use classic Discord-style interface for server/channel listing |
| `classic_change_guild_on_open` | boolean | true | change displayed guild when selecting a channel (classic channel list) |
#### style
Expand Down
2 changes: 2 additions & 0 deletions ci/used-icons.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ actions/call-stop-symbolic
status/microphone-disabled-symbolic
status/audio-volume-muted-symbolic
devices/camera-web-symbolic
status/user-available-symbolic
places/folder-symbolic
34 changes: 34 additions & 0 deletions res/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,37 @@
.message-text.failed {
color: red;
}

.guild-list-scroll > scrollbar {
border: none;
}

.guild-list-scroll > scrollbar slider {
border: none;
margin: 0px;
min-width: 0px;
min-height: 0px;
}

.channel-list .view:selected {
background-color: @theme_selected_bg_color;
}

.classic-guild-list > row {
padding-left: 0px;
box-shadow: none;
border: none;
outline: none;
}

.classic-guild-list > row:hover {
background: none;
}

.classic-guild-list-guild.has-unread {
background: radial-gradient(7px circle at left, @theme_selected_bg_color 50%, transparent 20%);
}

.classic-guild-list-guild box, .classic-guild-list-folder stack {
padding-left: 10px;
}
5 changes: 4 additions & 1 deletion src/abaddon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ Abaddon::Abaddon()
: m_settings(Platform::FindConfigFile())
, m_discord(GetSettings().UseMemoryDB) // stupid but easy
, m_emojis(GetResPath("/emojis.bin"))
, m_audio(GetSettings().Backends) {
#ifdef WITH_VOICE
, m_audio(GetSettings().Backends)
#endif
{
LoadFromSettings();

// todo: set user agent for non-client(?)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "channelscellrenderer.hpp"
#include "cellrendererchannels.hpp"
#include <gdkmm/general.h>
#include "abaddon.hpp"

Expand Down
File renamed without changes.
131 changes: 131 additions & 0 deletions src/components/channellist/channellist.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "channellist.hpp"

#include "abaddon.hpp"

ChannelList::ChannelList() {
get_style_context()->add_class("channel-browser-pane");

ConnectSignals();

m_guilds.set_halign(Gtk::ALIGN_START);

m_guilds_scroll.get_style_context()->add_class("guild-list-scroll");
m_guilds_scroll.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);

m_guilds.signal_guild_selected().connect([this](Snowflake guild_id) {
m_tree.SetSelectedGuild(guild_id);
});

m_guilds.signal_dms_selected().connect([this]() {
m_tree.SetSelectedDMs();
});

m_guilds.show();
m_tree.show();
m_guilds_scroll.add(m_guilds);
pack_start(m_guilds_scroll, false, false); // only take the space it needs
pack_start(m_tree, true, true); // use all the remaining space
}

void ChannelList::UpdateListing() {
m_tree.UpdateListing();
if (m_is_classic) m_guilds.UpdateListing();
}

void ChannelList::SetActiveChannel(Snowflake id, bool expand_to) {
if (Abaddon::Get().GetSettings().ClassicChangeGuildOnOpen) {
if (const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(id); channel.has_value() && channel->GuildID.has_value()) {
m_tree.SetSelectedGuild(*channel->GuildID);
} else {
m_tree.SetSelectedDMs();
}
}

m_tree.SetActiveChannel(id, expand_to);
}

void ChannelList::UseExpansionState(const ExpansionStateRoot &state) {
m_tree.UseExpansionState(state);
}

ExpansionStateRoot ChannelList::GetExpansionState() const {
return m_tree.GetExpansionState();
}

void ChannelList::UsePanedHack(Gtk::Paned &paned) {
m_tree.UsePanedHack(paned);
}

void ChannelList::SetClassic(bool value) {
m_is_classic = value;
m_tree.SetClassic(value);
m_guilds_scroll.set_visible(value);
}

void ChannelList::ConnectSignals() {
// TODO: if these all just travel upwards to the singleton then get rid of them but mayeb they dont

#ifdef WITH_LIBHANDY
m_tree.signal_action_open_new_tab().connect([this](Snowflake id) {
m_signal_action_open_new_tab.emit(id);
});
#endif

#ifdef WITH_VOICE
m_tree.signal_action_join_voice_channel().connect([this](Snowflake id) {
m_signal_action_join_voice_channel.emit(id);
});

m_tree.signal_action_disconnect_voice().connect([this]() {
m_signal_action_disconnect_voice.emit();
});
#endif

m_tree.signal_action_channel_item_select().connect([this](Snowflake id) {
m_signal_action_channel_item_select.emit(id);
});

m_tree.signal_action_guild_leave().connect([this](Snowflake id) {
m_signal_action_guild_leave.emit(id);
});

m_tree.signal_action_guild_settings().connect([this](Snowflake id) {
m_signal_action_guild_settings.emit(id);
});

m_guilds.signal_action_guild_leave().connect([this](Snowflake id) {
m_signal_action_guild_leave.emit(id);
});

m_guilds.signal_action_guild_settings().connect([this](Snowflake id) {
m_signal_action_guild_settings.emit(id);
});
}

#ifdef WITH_LIBHANDY
ChannelList::type_signal_action_open_new_tab ChannelList::signal_action_open_new_tab() {
return m_signal_action_open_new_tab;
}
#endif

#ifdef WITH_VOICE
ChannelList::type_signal_action_join_voice_channel ChannelList::signal_action_join_voice_channel() {
return m_signal_action_join_voice_channel;
}

ChannelList::type_signal_action_disconnect_voice ChannelList::signal_action_disconnect_voice() {
return m_signal_action_disconnect_voice;
}
#endif

ChannelList::type_signal_action_channel_item_select ChannelList::signal_action_channel_item_select() {
return m_signal_action_channel_item_select;
}

ChannelList::type_signal_action_guild_leave ChannelList::signal_action_guild_leave() {
return m_signal_action_guild_leave;
}

ChannelList::type_signal_action_guild_settings ChannelList::signal_action_guild_settings() {
return m_signal_action_guild_settings;
}
71 changes: 71 additions & 0 deletions src/components/channellist/channellist.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/paned.h>
#include "channellisttree.hpp"
#include "classic/guildlist.hpp"
#include "discord/snowflake.hpp"
#include "state.hpp"

// Contains the actual ChannelListTree and the classic listing if enabled
class ChannelList : public Gtk::HBox {
// have to proxy public and signals to underlying tree... ew!!!
public:
ChannelList();

void UpdateListing();
void SetActiveChannel(Snowflake id, bool expand_to);

// channel list should be populated when this is called
void UseExpansionState(const ExpansionStateRoot &state);
ExpansionStateRoot GetExpansionState() const;

void UsePanedHack(Gtk::Paned &paned);

void SetClassic(bool value);

private:
void ConnectSignals();

ChannelListTree m_tree;

Gtk::ScrolledWindow m_guilds_scroll;
GuildList m_guilds;

bool m_is_classic = false;

public:
using type_signal_action_channel_item_select = sigc::signal<void, Snowflake>;
using type_signal_action_guild_leave = sigc::signal<void, Snowflake>;
using type_signal_action_guild_settings = sigc::signal<void, Snowflake>;

#ifdef WITH_LIBHANDY
using type_signal_action_open_new_tab = sigc::signal<void, Snowflake>;
type_signal_action_open_new_tab signal_action_open_new_tab();
#endif

#ifdef WITH_VOICE
using type_signal_action_join_voice_channel = sigc::signal<void, Snowflake>;
using type_signal_action_disconnect_voice = sigc::signal<void>;

type_signal_action_join_voice_channel signal_action_join_voice_channel();
type_signal_action_disconnect_voice signal_action_disconnect_voice();
#endif

type_signal_action_channel_item_select signal_action_channel_item_select();
type_signal_action_guild_leave signal_action_guild_leave();
type_signal_action_guild_settings signal_action_guild_settings();

private:
type_signal_action_channel_item_select m_signal_action_channel_item_select;
type_signal_action_guild_leave m_signal_action_guild_leave;
type_signal_action_guild_settings m_signal_action_guild_settings;

#ifdef WITH_LIBHANDY
type_signal_action_open_new_tab m_signal_action_open_new_tab;
#endif

#ifdef WITH_VOICE
type_signal_action_join_voice_channel m_signal_action_join_voice_channel;
type_signal_action_disconnect_voice m_signal_action_disconnect_voice;
#endif
};
Loading

0 comments on commit 43f87ae

Please sign in to comment.