IRCClient: Add a little "(n)" indicator to window list for unread messages.

This commit is contained in:
Andreas Kling 2019-03-16 02:14:53 +01:00
parent 1394677528
commit b4f787090c
Notes: sideshowbarker 2024-07-19 15:02:02 +09:00
9 changed files with 68 additions and 14 deletions

View file

@ -12,8 +12,7 @@
#include <stdio.h>
IRCAppWindow::IRCAppWindow()
: GWindow()
, m_client("127.0.0.1", 6667)
: m_client("127.0.0.1", 6667)
{
set_title(String::format("IRC Client: %s@%s:%d", m_client.nickname().characters(), m_client.hostname().characters(), m_client.port()));
set_rect(200, 200, 600, 400);
@ -30,9 +29,15 @@ IRCAppWindow::~IRCAppWindow()
void IRCAppWindow::setup_client()
{
m_client.aid_create_window = [this] (void* owner, IRCWindow::Type type, const String& name) -> IRCWindow* {
m_client.aid_create_window = [this] (void* owner, IRCWindow::Type type, const String& name) {
return &create_window(owner, type, name);
};
m_client.aid_get_active_window = [this] {
return static_cast<IRCWindow*>(m_container->active_widget());
};
m_client.aid_update_window_list = [this] {
m_window_list->model()->update();
};
m_client.on_connect = [this] {
m_client.join_channel("#test");
@ -110,14 +115,15 @@ void IRCAppWindow::setup_widgets()
auto* horizontal_container = new GWidget(widget);
horizontal_container->set_layout(make<GBoxLayout>(Orientation::Horizontal));
auto* window_list = new GTableView(horizontal_container);
window_list->set_headers_visible(false);
window_list->set_alternating_row_colors(false);
window_list->set_model(OwnPtr<IRCWindowListModel>(m_client.client_window_list_model()));
window_list->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
window_list->set_preferred_size({ 120, 0 });
m_window_list = new GTableView(horizontal_container);
m_window_list->set_headers_visible(false);
m_window_list->set_alternating_row_colors(false);
m_window_list->set_model(OwnPtr<IRCWindowListModel>(m_client.client_window_list_model()));
m_window_list->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
m_window_list->set_preferred_size({ 120, 0 });
m_client.client_window_list_model()->on_activation = [this] (IRCWindow& window) {
m_container->set_active_widget(&window);
window.clear_unread_count();
};
m_container = new GStackWidget(horizontal_container);

View file

@ -20,11 +20,9 @@ private:
void setup_widgets();
IRCWindow& create_window(void* owner, IRCWindow::Type, const String& name);
IRCClient m_client;
GStackWidget* m_container { nullptr };
GTableView* m_window_list { nullptr };
RetainPtr<GAction> m_join_action;
RetainPtr<GAction> m_part_action;
RetainPtr<GAction> m_whois_action;

View file

@ -37,6 +37,7 @@ void IRCChannel::add_member(const String& name, char prefix)
void IRCChannel::add_message(char prefix, const String& name, const String& text)
{
window().did_add_message();
log().add_message(prefix, name, text);
dump();
}

View file

@ -237,8 +237,10 @@ void IRCClient::handle(const Message& msg, const String&)
if (msg.command == "PRIVMSG")
return handle_privmsg(msg);
if (msg.arguments.size() >= 2)
if (msg.arguments.size() >= 2) {
m_log->add_message(0, "Server", String::format("[%s] %s", msg.command.characters(), msg.arguments[1].characters()));
m_server_subwindow->did_add_message();
}
}
void IRCClient::send_privmsg(const String& target, const String& text)

View file

@ -30,11 +30,16 @@ public:
bool is_nick_prefix(char) const;
IRCWindow* current_window() { return aid_get_active_window(); }
const IRCWindow* current_window() const { return aid_get_active_window(); }
Function<void()> on_connect;
Function<void()> on_disconnect;
Function<void()> on_server_message;
Function<IRCWindow*(void*, IRCWindow::Type, const String&)> aid_create_window;
Function<IRCWindow*()> aid_get_active_window;
Function<void()> aid_update_window_list;
void register_subwindow(IRCWindow&);
void unregister_subwindow(IRCWindow&);

View file

@ -29,6 +29,7 @@ void IRCQuery::dump() const
void IRCQuery::add_message(char prefix, const String& name, const String& text)
{
window().did_add_message();
log().add_message(prefix, name, text);
dump();
}

View file

@ -61,3 +61,29 @@ void IRCWindow::set_log_buffer(const IRCLogBuffer& log_buffer)
m_log_buffer = &log_buffer;
m_table_view->set_model(OwnPtr<IRCLogBufferModel>((IRCLogBufferModel*)log_buffer.model()));
}
bool IRCWindow::is_active() const
{
return m_client.current_window() == this;
}
void IRCWindow::did_add_message()
{
if (!is_active()) {
++m_unread_count;
m_client.aid_update_window_list();
}
}
void IRCWindow::clear_unread_count()
{
if (!m_unread_count)
return;
m_unread_count = 0;
m_client.aid_update_window_list();
}
int IRCWindow::unread_count() const
{
return m_unread_count;
}

View file

@ -27,6 +27,13 @@ public:
void set_log_buffer(const IRCLogBuffer&);
bool is_active() const;
int unread_count() const;
void clear_unread_count();
void did_add_message();
IRCChannel& channel() { return *(IRCChannel*)m_owner; }
const IRCChannel& channel() const { return *(const IRCChannel*)m_owner; }
@ -34,6 +41,8 @@ public:
const IRCQuery& query() const { return *(const IRCQuery*)m_owner; }
private:
const char* class_name() const override { return "IRCWindow"; }
IRCClient& m_client;
void* m_owner { nullptr };
Type m_type;
@ -41,4 +50,5 @@ private:
GTableView* m_table_view { nullptr };
GTextEditor* m_text_editor { nullptr };
RetainPtr<IRCLogBuffer> m_log_buffer;
int m_unread_count { 0 };
};

View file

@ -43,7 +43,12 @@ GTableModel::ColumnMetadata IRCWindowListModel::column_metadata(int column) cons
GVariant IRCWindowListModel::data(const GModelIndex& index, Role) const
{
switch (index.column()) {
case Column::Name: return m_client.window_at(index.row()).name();
case Column::Name: {
auto& window = m_client.window_at(index.row());
if (!window.unread_count())
return window.name();
return String::format("%s (%d)\n", window.name().characters(), window.unread_count());
}
}
ASSERT_NOT_REACHED();
}