Commit 2418f1c8 authored by Mohammed Sadiq's avatar Mohammed Sadiq Committed by Mohammed Sadiq
Browse files

Add ChattyPpChatInfo

parent 6dec1914
......@@ -37,6 +37,8 @@ src/chatty-window.c
src/chatty-window.h
src/dialogs/chatty-info-dialog.c
src/dialogs/chatty-info-dialog.h
src/dialogs/chatty-pp-chat-info.c
src/dialogs/chatty-pp-chat-info.h
src/dialogs/chatty-new-chat-dialog.c
src/dialogs/chatty-new-chat-dialog.h
src/dialogs/chatty-new-muc-dialog.c
......@@ -58,6 +60,7 @@ src/ui/chatty-contact-row.ui
src/ui/chatty-dialog-join-muc.ui
src/ui/chatty-dialog-new-chat.ui
src/ui/chatty-info-dialog.ui
src/ui/chatty-pp-chat-info.ui
src/ui/chatty-fp-row.ui
src/ui/chatty-list-row.ui
src/ui/chatty-ma-account-details.ui
......
......@@ -7,6 +7,7 @@
<file preprocess="xml-stripblanks">ui/chatty-contact-row.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-image-item.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-message-row.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-pp-chat-info.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-info-dialog.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-ma-account-details.ui</file>
<file preprocess="xml-stripblanks">ui/chatty-pp-account-details.ui</file>
......
/* -*- mode: c; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* chatty-pp-chat-info.c
*
* Copyright 2021 Purism SPC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author(s):
* Mohammed Sadiq <sadiq@sadiqpk.org>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#define G_LOG_DOMAIN "chatty-pp-chat-info"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <glib/gi18n.h>
#include "chatty-avatar.h"
#include "chatty-list-row.h"
#include "chatty-fp-row.h"
#include "chatty-pp-chat.h"
#include "chatty-pp-chat-info.h"
#include "chatty-log.h"
struct _ChattyPpChatInfo
{
HdyPreferencesPage parent_instance;
ChattyChat *chat;
GtkWidget *room_name;
GtkWidget *avatar_button;
GtkWidget *avatar;
GtkWidget *room_topic_view;
GtkTextBuffer *topic_buffer;
GtkWidget *name_label;
GtkWidget *user_id_title;
GtkWidget *user_id_label;
GtkWidget *encryption_label;
GtkWidget *status_label;
GtkWidget *settings_label;
GtkWidget *notification_switch;
GtkWidget *show_status_switch;
GtkWidget *encryption_switch;
GtkWidget *key_list;
GtkWidget *user_list_label;
GtkWidget *user_list;
GtkWidget *avatar_chooser_dialog;
GBinding *binding;
};
G_DEFINE_TYPE (ChattyPpChatInfo, chatty_pp_chat_info, HDY_TYPE_PREFERENCES_PAGE)
static void
pp_info_avatar_button_clicked_cb (ChattyPpChatInfo *self)
{
GtkDialog *dialog;
g_autofree char *file_name = NULL;
int response;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
dialog = GTK_DIALOG (self->avatar_chooser_dialog);
response = gtk_dialog_run (dialog);
gtk_widget_hide (GTK_WIDGET (dialog));
if (response == GTK_RESPONSE_APPLY)
file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (file_name)
chatty_item_set_avatar_async (CHATTY_ITEM (self->chat), file_name,
NULL, NULL, NULL);
}
static void
pp_chat_info_edit_topic_clicked_cb (ChattyPpChatInfo *self,
GtkToggleButton *edit_button)
{
gboolean editable;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
g_assert (GTK_IS_TOGGLE_BUTTON (edit_button));
editable = gtk_toggle_button_get_active (edit_button);
gtk_text_view_set_editable (GTK_TEXT_VIEW (self->room_topic_view), editable);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (self->room_topic_view), editable);
gtk_widget_set_can_focus (self->room_topic_view, editable);
if (editable) {
gtk_widget_grab_focus (self->room_topic_view);
} else if (gtk_text_buffer_get_modified (self->topic_buffer)) {
g_autofree char *text = NULL;
g_object_get (self->topic_buffer, "text", &text, NULL);
chatty_chat_set_topic (CHATTY_CHAT (self->chat), text);
}
gtk_text_buffer_set_modified (self->topic_buffer, FALSE);
}
static void
pp_chat_info_notification_switch_changed_cb (ChattyPpChatInfo *self)
{
gboolean active;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
active = gtk_switch_get_active (GTK_SWITCH (self->notification_switch));
chatty_pp_chat_set_show_notifications (CHATTY_PP_CHAT (self->chat), active);
}
static void
pp_chat_info_show_status_switch_changed_cb (ChattyPpChatInfo *self)
{
gboolean active;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
g_return_if_fail (CHATTY_IS_PP_CHAT (self->chat));
active = gtk_switch_get_active (GTK_SWITCH (self->show_status_switch));
chatty_pp_chat_set_show_status_msg (CHATTY_PP_CHAT (self->chat), active);
}
static void
pp_chat_info_encrypt_changed_cb (ChattyPpChatInfo *self)
{
const char *status_msg = "";
ChattyEncryption encryption;
gboolean has_encryption;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
encryption = chatty_chat_get_encryption (self->chat);
has_encryption = encryption != CHATTY_ENCRYPTION_UNSUPPORTED;
gtk_widget_set_visible (self->settings_label, CHATTY_IS_PP_CHAT (self->chat));
gtk_widget_set_visible (self->encryption_switch,
has_encryption && CHATTY_IS_PP_CHAT (self->chat));
switch (encryption) {
case CHATTY_ENCRYPTION_UNSUPPORTED:
case CHATTY_ENCRYPTION_UNKNOWN:
status_msg = _("Encryption is not available");
break;
case CHATTY_ENCRYPTION_ENABLED:
status_msg = _("This chat is encrypted");
break;
case CHATTY_ENCRYPTION_DISABLED:
status_msg = _("This chat is not encrypted");
break;
default:
g_return_if_reached ();
}
gtk_label_set_text (GTK_LABEL (self->encryption_label), status_msg);
}
static void
pp_chat_info_list_fp_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
ChattyPpChatInfo *self = user_data;
ChattyPpChat *chat;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
chat = CHATTY_PP_CHAT (self->chat);
if (!chatty_pp_chat_load_fp_list_finish (chat, result, NULL)) {
gtk_widget_hide (self->key_list);
gtk_label_set_text (GTK_LABEL (self->encryption_label), _("Encryption not available"));
} else {
gtk_widget_show (self->key_list);
gtk_list_box_bind_model (GTK_LIST_BOX (self->key_list),
chatty_pp_chat_get_fp_list (chat),
(GtkListBoxCreateWidgetFunc) chatty_fp_row_new,
NULL, NULL);
}
}
static void
chatty_pp_chat_info_list_users (ChattyPpChatInfo *self)
{
GListModel *user_list;
g_autofree char *count_str = NULL;
guint n_items;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
user_list = chatty_chat_get_users (self->chat);
n_items = g_list_model_get_n_items (user_list);
count_str = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%u Member",
"%u Members", n_items),
n_items);
gtk_label_set_text (GTK_LABEL (self->user_list_label), count_str);
gtk_list_box_bind_model (GTK_LIST_BOX (self->user_list), user_list,
(GtkListBoxCreateWidgetFunc)chatty_list_row_new,
NULL, NULL);
}
static void
chatty_pp_chat_info_update (ChattyPpChatInfo *self)
{
ChattyProtocol protocol;
g_assert (CHATTY_IS_PP_CHAT_INFO (self));
if (!self->chat)
return;
protocol = chatty_item_get_protocols (CHATTY_ITEM (self->chat));
chatty_avatar_set_item (CHATTY_AVATAR (self->avatar), CHATTY_ITEM (self->chat));
self->binding = g_object_bind_property (self->chat, "encrypt",
self->encryption_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_signal_connect_object (self->chat, "notify::encrypt",
G_CALLBACK (pp_chat_info_encrypt_changed_cb),
self,
G_CONNECT_SWAPPED);
pp_chat_info_encrypt_changed_cb (self);
if (protocol == CHATTY_PROTOCOL_SMS) {
gtk_label_set_text (GTK_LABEL (self->user_id_title), _("Phone Number:"));
} else if (protocol == CHATTY_PROTOCOL_XMPP) {
gtk_label_set_text (GTK_LABEL (self->user_id_title), _("XMPP ID:"));
gtk_widget_show (GTK_WIDGET (self->status_label));
gtk_label_set_text (GTK_LABEL (self->status_label),
chatty_pp_chat_get_status (CHATTY_PP_CHAT (self->chat)));
} else if (protocol == CHATTY_PROTOCOL_MATRIX) {
gtk_label_set_text (GTK_LABEL (self->user_id_title), _("Matrix ID:"));
gtk_widget_set_sensitive (self->avatar_button, FALSE);
gtk_widget_hide (self->user_id_label);
} else if (protocol == CHATTY_PROTOCOL_TELEGRAM) {
gtk_label_set_text (GTK_LABEL (self->user_id_title), _("Telegram ID:"));
}
if (chatty_chat_is_im (self->chat))
gtk_label_set_text (GTK_LABEL (self->user_id_label),
chatty_chat_get_chat_name (self->chat));
gtk_label_set_text (GTK_LABEL (self->name_label),
chatty_item_get_name (CHATTY_ITEM (self->chat)));
if (chatty_chat_is_im (self->chat)) {
gtk_widget_show (self->user_id_label);
gtk_widget_show (self->name_label);
gtk_widget_show (self->avatar_button);
} else {
gtk_widget_hide (self->user_id_label);
gtk_widget_hide (self->name_label);
gtk_widget_show (self->room_name);
gtk_label_set_text (GTK_LABEL (self->room_name),
chatty_item_get_name (CHATTY_ITEM (self->chat)));
}
gtk_list_box_bind_model (GTK_LIST_BOX (self->key_list),
NULL, NULL, NULL, NULL);
if (protocol == CHATTY_PROTOCOL_XMPP &&
chatty_chat_is_im (self->chat)) {
gtk_widget_show (self->encryption_label);
gtk_widget_show (self->status_label);
chatty_pp_chat_load_fp_list_async (CHATTY_PP_CHAT (self->chat),
pp_chat_info_list_fp_cb, self);
} else {
gtk_widget_hide (self->encryption_label);
gtk_widget_hide (self->status_label);
}
gtk_widget_set_visible (self->notification_switch,
protocol != CHATTY_PROTOCOL_MATRIX);
if (protocol != CHATTY_PROTOCOL_MATRIX)
gtk_switch_set_state (GTK_SWITCH (self->notification_switch),
chatty_pp_chat_get_show_notifications (CHATTY_PP_CHAT (self->chat)));
if ((protocol == CHATTY_PROTOCOL_XMPP ||
protocol == CHATTY_PROTOCOL_TELEGRAM) &&
!chatty_chat_is_im (self->chat)) {
gtk_widget_show (self->show_status_switch);
} else {
gtk_widget_hide (self->show_status_switch);
}
if (protocol == CHATTY_PROTOCOL_XMPP &&
!chatty_chat_is_im (self->chat)) {
gtk_widget_show (self->room_topic_view);
gtk_widget_show (self->user_list);
chatty_pp_chat_info_list_users (self);
gtk_switch_set_state (GTK_SWITCH (self->show_status_switch),
chatty_pp_chat_get_show_status_msg (CHATTY_PP_CHAT (self->chat)));
gtk_text_buffer_set_text (self->topic_buffer,
chatty_chat_get_topic (self->chat), -1);
} else {
gtk_widget_hide (self->user_list);
gtk_widget_hide (self->show_status_switch);
gtk_widget_hide (self->room_topic_view);
}
}
static void
chatty_pp_chat_info_finalize (GObject *object)
{
ChattyPpChatInfo *self = (ChattyPpChatInfo *)object;
g_clear_object (&self->chat);
G_OBJECT_CLASS (chatty_pp_chat_info_parent_class)->finalize (object);
}
static void
chatty_pp_chat_info_class_init (ChattyPpChatInfoClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = chatty_pp_chat_info_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
"/sm/puri/Chatty/"
"ui/chatty-pp-chat-info.ui");
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, room_name);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, avatar_button);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, avatar);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, room_topic_view);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, name_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, user_id_title);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, user_id_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, encryption_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, status_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, settings_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, notification_switch);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, show_status_switch);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, encryption_switch);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, key_list);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, user_list_label);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, user_list);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, avatar_chooser_dialog);
gtk_widget_class_bind_template_child (widget_class, ChattyPpChatInfo, topic_buffer);
gtk_widget_class_bind_template_callback (widget_class, pp_info_avatar_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, pp_chat_info_edit_topic_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, pp_chat_info_notification_switch_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, pp_chat_info_show_status_switch_changed_cb);
}
static void
chatty_pp_chat_info_init (ChattyPpChatInfo *self)
{
GtkWidget *clamp, *window;
gtk_widget_init_template (GTK_WIDGET (self));
clamp = gtk_widget_get_ancestor (self->avatar, HDY_TYPE_CLAMP);
if (clamp) {
hdy_clamp_set_maximum_size (HDY_CLAMP (clamp), 360);
hdy_clamp_set_tightening_threshold (HDY_CLAMP (clamp), 320);
}
window = gtk_widget_get_ancestor (self->avatar, GTK_TYPE_DIALOG);
if (window)
gtk_window_set_transient_for (GTK_WINDOW (self->avatar_chooser_dialog),
GTK_WINDOW (window));
}
GtkWidget *
chatty_pp_chat_info_new (void)
{
return g_object_new (CHATTY_TYPE_PP_CHAT_INFO, NULL);
}
ChattyChat *
chatty_pp_chat_info_get_item (ChattyPpChatInfo *self)
{
g_return_val_if_fail (CHATTY_IS_PP_CHAT_INFO (self), NULL);
return self->chat;
}
void
chatty_pp_chat_info_set_item (ChattyPpChatInfo *self,
ChattyChat *chat)
{
g_return_if_fail (CHATTY_IS_PP_CHAT_INFO (self));
g_return_if_fail (!chat || CHATTY_IS_CHAT (chat));
if (!g_set_object (&self->chat, chat))
return;
gtk_text_buffer_set_text (self->topic_buffer, "", 0);
gtk_widget_hide (self->key_list);
g_clear_object (&self->binding);
gtk_container_foreach (GTK_CONTAINER (self->key_list),
(GtkCallback)gtk_widget_destroy, NULL);
if (self->chat)
g_signal_handlers_disconnect_by_func (self->chat,
pp_chat_info_encrypt_changed_cb,
self);
chatty_pp_chat_info_update (self);
}
/* -*- mode: c; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* chatty-pp-chat-info.h
*
* Copyright 2021 Purism SPC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author(s):
* Mohammed Sadiq <sadiq@sadiqpk.org>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <gtk/gtk.h>
#include "chatty-chat.h"
G_BEGIN_DECLS
#define CHATTY_TYPE_PP_CHAT_INFO (chatty_pp_chat_info_get_type ())
G_DECLARE_FINAL_TYPE (ChattyPpChatInfo, chatty_pp_chat_info, CHATTY, PP_CHAT_INFO, HdyPreferencesPage)
GtkWidget *chatty_pp_chat_info_new (void);
ChattyChat *chatty_pp_chat_info_get_item (ChattyPpChatInfo *self);
void chatty_pp_chat_info_set_item (ChattyPpChatInfo *self,
ChattyChat *chat);
G_END_DECLS
......@@ -14,6 +14,7 @@ libsrc = [
'contrib/gtkslicelistmodel.c',
'dialogs/chatty-ma-account-details.c',
'dialogs/chatty-pp-account-details.c',
'dialogs/chatty-pp-chat-info.c',
'matrix/matrix-api.c',
'matrix/matrix-enc.c',
'matrix/matrix-db.c',
......@@ -60,6 +61,7 @@ ui_files = files (
'ui/chatty-message-row.ui',
# FIXME
# 'ui/chatty-pp-account-details.ui',
# 'ui/chatty-pp-user-info.ui',
'ui/chatty-settings-dialog.ui',
'ui/chatty-window.ui',
)
......
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ChattyPpChatInfo" parent="HdyPreferencesPage">
<property name="visible">1</property>
<child>
<object class="HdyPreferencesGroup">
<property name="visible">1</property>
<!-- Room name -->
<child>
<object class="GtkLabel" id="room_name">
<property name="visible" bind-source="avatar_button" bind-property="visible"
bind-flags="invert-boolean|bidirectional|sync-create"/>
<attributes>
<attribute name="scale" value="2"/>
</attributes>
</object>
</child>
<child>
<object class="GtkButton" id="avatar_button">
<property name="visible" bind-source="avatar" bind-property="visible"
bind-flags="sync-create"/>
<property name="hexpand">1</property>
<property name="halign">center</property>
<property name="can-focus">0</property>
<property name="focus-on-click">0</property>
<property name="receives_default">0</property>
<property name="margin-bottom">24</property>
<signal name="clicked" handler="pp_info_avatar_button_clicked_cb" swapped="yes"/>
<child>
<object class="ChattyAvatar" id="avatar">
<property name="visible">1</property>
<property name="size">96</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="HdyPreferencesGroup">
<property name="visible" bind-source="room_topic_view" bind-property="visible"
bind-flags="sync-create"/>
<child>
<object class="GtkBox">
<property name="visible">1</property>
<property name="spacing">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible" bind-source="room_topic_view" bind-property="visible"
bind-flags="sync-create"/>
<property name="halign">start</property>
<property name="label" translatable="yes">Room topic</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible" bind-source="room_topic_view" bind-property="visible"
bind-flags="sync-create"/>
<property name="spacing">6</property>
<!-- Topic text view -->
<child>
<object class="GtkFrame">
<property name="visible">1</property>
<child>
<object class="GtkTextView" id="room_topic_view">
<property name="visible">1</property>
<property name="hexpand">1</property>
<property name="cursor-visible">0</property>
<property name="left-margin">6</property>
<property name="right-margin">6</property>
<property name="top-margin">6</property>
<property name="bottom-margin">6</property>
<property name="wrap-mode">word-char</property>
<property name="buffer">topic_buffer</property>
</object>
</child>
</object>
</child>
<!-- Topic edit button -->
<child>
<object class="GtkToggleButton" id="edit_topic_button">
<property name="visible">1</property>