Mark conversation as read on movement
This commit is contained in:
@@ -6,6 +6,9 @@ public class MainWindow : Adw.ApplicationWindow
|
||||
private ConversationListView conversation_list_view;
|
||||
private TranscriptContainerView transcript_container_view;
|
||||
|
||||
private EventControllerMotion _motion_controller = new EventControllerMotion();
|
||||
private bool _motion_queued = false;
|
||||
|
||||
public MainWindow () {
|
||||
Object (title: "Kordophone");
|
||||
|
||||
@@ -20,14 +23,59 @@ public class MainWindow : Adw.ApplicationWindow
|
||||
split_view.sidebar = conversation_list_page;
|
||||
|
||||
transcript_container_view = new TranscriptContainerView ();
|
||||
transcript_container_view.on_send.connect (on_transcript_send);
|
||||
|
||||
var transcript_page = new NavigationPage (transcript_container_view, "Transcript");
|
||||
split_view.content = transcript_page;
|
||||
|
||||
var show_settings_action = new SimpleAction ("settings", null);
|
||||
show_settings_action.activate.connect(show_settings);
|
||||
add_action(show_settings_action);
|
||||
|
||||
_motion_controller.motion.connect((x, y) => {
|
||||
queue_motion();
|
||||
});
|
||||
_motion_controller.set_propagation_phase(PropagationPhase.CAPTURE);
|
||||
split_view.add_controller(_motion_controller);
|
||||
}
|
||||
|
||||
private void queue_motion() {
|
||||
if (_motion_queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
_motion_queued = true;
|
||||
GLib.Timeout.add(500, () => {
|
||||
_motion_queued = false;
|
||||
on_motion();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private void on_motion() {
|
||||
var selected_conversation = transcript_container_view.transcript_view.model?.conversation;
|
||||
if (selected_conversation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var list_model = conversation_list_view.conversation_model;
|
||||
var conversation_in_list = list_model.get_conversation(selected_conversation.guid);
|
||||
if (conversation_in_list == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (conversation_in_list.unread_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
GLib.message("Marking conversation as read on motion: %s", selected_conversation.guid);
|
||||
Repository.get_instance().mark_conversation_as_read(selected_conversation.guid);
|
||||
} catch (Error e) {
|
||||
GLib.warning("Failed to mark conversation as read: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void show_settings () {
|
||||
@@ -40,8 +88,8 @@ public class MainWindow : Adw.ApplicationWindow
|
||||
if (conversation == null) {
|
||||
transcript_view.model = null;
|
||||
} else {
|
||||
if (transcript_view.model == null || transcript_view.model.conversation_guid != conversation.guid) {
|
||||
transcript_view.model = new MessageListModel (conversation.guid);
|
||||
if (transcript_view.model == null || transcript_view.model.conversation.guid != conversation.guid) {
|
||||
transcript_view.model = new MessageListModel (conversation);
|
||||
transcript_view.title = conversation.display_name;
|
||||
|
||||
try {
|
||||
@@ -53,29 +101,4 @@ public class MainWindow : Adw.ApplicationWindow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void on_transcript_send(TranscriptContainerView view) {
|
||||
var body = view.message_body;
|
||||
var attachment_guids = view.attachment_guids;
|
||||
|
||||
// Strip empty space at the beginning and end of the body
|
||||
body = body.strip();
|
||||
|
||||
if (transcript_container_view.transcript_view.model == null) {
|
||||
GLib.warning("No conversation selected");
|
||||
return;
|
||||
}
|
||||
|
||||
var selected_conversation = transcript_container_view.transcript_view.model.conversation_guid;
|
||||
if (selected_conversation == null) {
|
||||
GLib.warning("No conversation selected");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Repository.get_instance().send_message(selected_conversation, body, attachment_guids.to_array());
|
||||
} catch (Error e) {
|
||||
GLib.warning("Failed to send message: %s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ using Gtk;
|
||||
|
||||
public class ConversationListView : Adw.Bin
|
||||
{
|
||||
public ConversationListModel conversation_model { get; private set; }
|
||||
public signal void conversation_selected(Conversation conversation);
|
||||
|
||||
private Adw.ToolbarView container;
|
||||
private ListBox list_box;
|
||||
private ScrolledWindow scrolled_window;
|
||||
private Adw.HeaderBar header_bar;
|
||||
private ConversationListModel conversation_model;
|
||||
|
||||
private string? selected_conversation_guid = null;
|
||||
private bool selection_update_queued = false;
|
||||
|
||||
@@ -15,16 +15,16 @@ public class MessageListModel : Object, ListModel
|
||||
}
|
||||
}
|
||||
|
||||
public string conversation_guid { get; private set; }
|
||||
public Conversation conversation { get; private set; }
|
||||
|
||||
private ArrayList<Message> _messages;
|
||||
private HashSet<string> participants = new HashSet<string>();
|
||||
private ulong update_handler_id = 0;
|
||||
private ulong reconnected_handler_id = 0;
|
||||
|
||||
public MessageListModel(string conversation_guid) {
|
||||
public MessageListModel(Conversation conversation) {
|
||||
_messages = new ArrayList<Message>();
|
||||
this.conversation_guid = conversation_guid;
|
||||
this.conversation = conversation;
|
||||
}
|
||||
|
||||
~MessageListModel() {
|
||||
@@ -69,7 +69,7 @@ public class MessageListModel : Object, ListModel
|
||||
try {
|
||||
bool first_load = _messages.size == 0;
|
||||
|
||||
Message[] messages = Repository.get_instance().get_messages(conversation_guid);
|
||||
Message[] messages = Repository.get_instance().get_messages(conversation.guid);
|
||||
|
||||
// Clear existing set
|
||||
uint old_count = _messages.size;
|
||||
@@ -108,8 +108,16 @@ public class MessageListModel : Object, ListModel
|
||||
messages_changed();
|
||||
}
|
||||
|
||||
public void mark_as_read() {
|
||||
try {
|
||||
Repository.get_instance().mark_conversation_as_read(conversation.guid);
|
||||
} catch (Error e) {
|
||||
warning("Failed to mark conversation as read: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void got_messages_updated(string conversation_guid) {
|
||||
if (conversation_guid == this.conversation_guid) {
|
||||
if (conversation_guid == this.conversation.guid) {
|
||||
load_messages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using GLib;
|
||||
class TranscriptContainerView : Adw.Bin
|
||||
{
|
||||
public TranscriptView transcript_view;
|
||||
public signal void on_send(TranscriptContainerView view);
|
||||
|
||||
private Box container;
|
||||
private Button send_button;
|
||||
@@ -225,7 +224,7 @@ class TranscriptContainerView : Adw.Bin
|
||||
|
||||
private void on_request_send() {
|
||||
if (can_send) {
|
||||
on_send(this);
|
||||
on_send();
|
||||
|
||||
// Clear the message text
|
||||
message_buffer.set_text("");
|
||||
@@ -240,6 +239,30 @@ class TranscriptContainerView : Adw.Bin
|
||||
}
|
||||
}
|
||||
|
||||
private void on_send() {
|
||||
var body = message_body;
|
||||
|
||||
// Strip empty space at the beginning and end of the body
|
||||
body = body.strip();
|
||||
|
||||
if (transcript_view.model == null) {
|
||||
GLib.warning("No conversation selected");
|
||||
return;
|
||||
}
|
||||
|
||||
var selected_conversation = transcript_view.model.conversation;
|
||||
if (selected_conversation == null) {
|
||||
GLib.warning("No conversation selected");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Repository.get_instance().send_message(selected_conversation.guid, body, attachment_guids.to_array());
|
||||
} catch (Error e) {
|
||||
GLib.warning("Failed to send message: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_attach_button_clicked() {
|
||||
var dialog = new Gtk.FileDialog();
|
||||
dialog.set_title("Select attachment");
|
||||
|
||||
@@ -25,6 +25,8 @@ private class TranscriptDrawingArea : Widget
|
||||
private GestureClick _click_gesture = new GestureClick();
|
||||
private Gdk.Rectangle? _click_bounding_box = null;
|
||||
|
||||
private EventControllerMotion _motion_controller = new EventControllerMotion();
|
||||
|
||||
private const bool debug_viewport = false;
|
||||
private uint? _tick_callback_id = null;
|
||||
private HashMap<string, ChatItemAnimation> _animations = new HashMap<string, ChatItemAnimation>();
|
||||
@@ -40,6 +42,22 @@ private class TranscriptDrawingArea : Widget
|
||||
});
|
||||
add_controller(_click_gesture);
|
||||
|
||||
_motion_controller.motion.connect((x, y) => {
|
||||
if (self == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only print motion events if window is active/focused
|
||||
var window = self.get_native() as Gtk.Window;
|
||||
if (window == null || !window.is_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.on_mouse_motion(x, y);
|
||||
});
|
||||
_motion_controller.set_propagation_phase(PropagationPhase.CAPTURE);
|
||||
add_controller(_motion_controller);
|
||||
|
||||
SimpleAction copy_action = new SimpleAction("copy", null);
|
||||
copy_action.activate.connect(() => {
|
||||
if (_click_bounding_box != null) {
|
||||
@@ -172,6 +190,10 @@ private class TranscriptDrawingArea : Widget
|
||||
animation_tick();
|
||||
}
|
||||
|
||||
private void on_mouse_motion(double x, double y) {
|
||||
// TODO: Will be making temporary text views here.
|
||||
}
|
||||
|
||||
private void on_right_click() {
|
||||
var menu_model = new Menu();
|
||||
menu_model.append("Copy", "transcript.copy");
|
||||
|
||||
Reference in New Issue
Block a user