~nicohman/signal-rs

8d4114c4eea155a438cbdb3c591071bedab0d129 — nicohman 1 year, 17 days ago edbf124
Show specific messages
2 files changed, 48 insertions(+), 67 deletions(-)

M src/main.rs
M src/signal.rs
M src/main.rs => src/main.rs +39 -49
@@ 15,25 15,17 @@ extern crate gio;
extern crate glib;
extern crate gtk;
extern crate tokio_tungstenite;
use crossbeam_channel::*;
use futures_util::sink::SinkExt;
use futures_util::{future, pin_mut, StreamExt};
use serde::*;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::prelude::*;
use futures_util::StreamExt;
use tokio::sync::mpsc::*;
use tokio_tungstenite::connect_async;
const CONNECTION: &'static str = "ws://localhost:9080/ws";
const CONNECTION: &str = "ws://localhost:9080/ws";
mod signal;
use gio::prelude::*;
use glib::clone;
use glib::prelude::*;
use gtk::prelude::*;
use gtk::*;
use signal::*;
use std::borrow::*;
use std::boxed::Box;
use std::cell::*;
use std::collections::*;
use std::env::args;
use std::rc::*;


@@ 41,22 33,22 @@ use tungstenite::*;
use url::Url;
pub struct SignalState {
    pub chats: HashMap<i32, Chat>,
    pub message_box: Rc<gtk::Box>,
    pub app_box: gtk::Box,
    pub message_box: Rc<Box>,
    pub app_box: Box,
    pub contacts: HashMap<String, Contact>,
    pub messages: HashMap<String, (HashMap<i32, Message>, gtk::Box)>,
    pub messages: HashMap<String, (HashMap<i32, Message>, Box)>,
    pub current: Option<String>,
}
impl SignalState {
    pub fn new(app: &gtk::Box) -> SignalState {
        let mut message_box = Rc::new(gtk::Box::new(Orientation::Vertical, 8));
        let mut app_box = gtk::Box::new(Orientation::Vertical, 8);
    pub fn new(_app: &Box) -> SignalState {
        let message_box = Rc::new(Box::new(Orientation::Vertical, 8));
        let app_box = Box::new(Orientation::Vertical, 8);
        app_box.add(&(*message_box));
        SignalState {
            chats: HashMap::new(),
            contacts: HashMap::new(),
            message_box: message_box,
            app_box: app_box,
            message_box,
            app_box,
            messages: HashMap::new(),
            current: None,
        }


@@ 69,7 61,7 @@ impl SignalState {
        if let Some(b) = self.messages.get(&tel) {
            b.1.show();
        } else {
            let b = gtk::Box::new(Orientation::Vertical, 8);
            let b = Box::new(Orientation::Vertical, 8);
            b.show();
            self.message_box.add(&b);
            self.messages.insert(tel.clone(), (HashMap::new(), b));


@@ 77,7 69,7 @@ impl SignalState {
    }
    pub fn add_message(&mut self, message: SignalMessage) {
        if !self.messages.contains_key(&message.source) {
            let b = gtk::Box::new(Orientation::Vertical, 8);
            let b = Box::new(Orientation::Vertical, 8);
            self.message_box.add(&b);
            self.messages
                .insert(message.source.clone(), (HashMap::new(), b));


@@ 129,6 121,9 @@ impl SignalState {
                    }
                }
            }
            SignalResponse::ShowMessages(to_show) => {
                self.show_messages(to_show);
            }
            SignalResponse::MessageList(message_list) => {
                self.add_messages(message_list.messages);
            }


@@ 141,12 136,12 @@ impl SignalState {
}
pub struct Message {
    pub msg: SignalMessage,
    pub ui: gtk::Box,
    pub ui: Box,
    pub label: Label,
}
impl Message {
    pub fn new(msg: SignalMessage) -> Message {
        let msg_box = gtk::Box::new(Orientation::Vertical, 6);
        let msg_box = Box::new(Orientation::Vertical, 6);
        let label = Label::new(Some(&msg.message));
        msg_box.add(&label);
        let context = msg_box.get_style_context();


@@ 164,15 159,15 @@ impl Message {
#[tokio::main]
async fn main() -> Result<()> {
    let css = include_str!("style.css");
    let mut total: Vec<SignalResponse> = vec![];
    let application = gtk::Application::new(Some("com.nicohman"), Default::default()).unwrap();
    let _total: Vec<SignalResponse> = vec![];
    let application = Application::new(Some("com.nicohman"), Default::default()).unwrap();
    application.connect_activate(move |app| {
        let provider = CssProvider::new();
        provider.load_from_data(css.as_bytes()).unwrap();
        let (resSender, mut resReceiver) =
        let (res_sender, res_receiver) =
            glib::MainContext::channel::<SignalResponse>(glib::PRIORITY_DEFAULT);
        let l_res_sender = resSender.clone();
        let (reqSender, mut reqReceiver) = unbounded_channel::<SignalRequest>();
        let l_res_sender = res_sender.clone();
        let (req_sender, mut req_receiver) = unbounded_channel::<SignalRequest>();
        tokio::spawn(async move {
            let (socket, _response) = connect_async(Url::parse(CONNECTION).unwrap())
                .await


@@ 181,10 176,9 @@ async fn main() -> Result<()> {
            loop {
                tokio::select! {
                    next = session.stream.next() => {
                        println!("Got response");
                        resSender.send(next.unwrap());
                        res_sender.send(next.unwrap());
                    },
                    inc = reqReceiver.recv() => {
                    inc = req_receiver.recv() => {
                        if let Some(v) = inc {
                            session.send(v).await;
                        }


@@ 195,43 189,39 @@ async fn main() -> Result<()> {
        StyleContext::add_provider_for_screen(
            &gdk::Screen::get_default().expect("Error initializing gtk css provider."),
            &provider,
            gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
            STYLE_PROVIDER_PRIORITY_APPLICATION,
        );
        let window = gtk::ApplicationWindow::new(app);
        let mut app_box = gtk::Box::new(Orientation::Vertical, 6);
        let window = ApplicationWindow::new(app);
        let app_box = Box::new(Orientation::Vertical, 6);
        let mut state = SignalState::new(&app_box);
        window.set_title("Signal");
        window.set_border_width(10);
        window.set_position(gtk::WindowPosition::Center);
        window.set_position(WindowPosition::Center);
        window.set_default_size(350, 70);
        let input = gtk::EntryBuilder::new().build();
        let show_input = gtk::Entry::new();
        let input = EntryBuilder::new().build();
        let show_input = Entry::new();
        show_input.set_placeholder_text(Some("Number to show messages from"));
        let show_button = Button::with_label("Show messages");
        let button = gtk::Button::with_label("Send debug text");
        let button = Button::with_label("Send debug text");
        show_button.connect_clicked(
            clone!( @strong l_res_sender, @weak show_input, @strong reqSender => move |_| {
                let inp = show_input.get_buffer().get_text().clone();
                reqSender.send(SignalRequest::GetMessageList{ id: inp.clone()});
            clone!( @strong l_res_sender, @weak show_input, @strong req_sender => move |_| {
                let inp = show_input.get_buffer().get_text();
                req_sender.send(SignalRequest::GetMessageList{ id: inp.clone()});
                l_res_sender.send(SignalResponse::ShowMessages(inp));
            }),
        );
        button.connect_clicked(clone!( @weak input => move |_| {
            reqSender.send(SignalRequest::SendMessage {
                to: "".to_owned(),
                message: input.get_buffer().get_text().clone(),
        button.connect_clicked(clone!( @weak input, @weak show_input => move |_| {
            req_sender.send(SignalRequest::SendMessage {
                to: show_input.get_buffer().get_text(),
                message: input.get_buffer().get_text(),
            });
        }));
        let text = gtk::TextViewBuilder::new()
            .wrap_mode(WrapMode::Word)
            .build();
        app_box.add(&text);
        state.app_box.add(&show_input);
        state.app_box.add(&show_button);
        state.app_box.add(&input);
        state.app_box.add(&button);
        window.add(&state.app_box);
        resReceiver.attach(None, move |value| {
        res_receiver.attach(None, move |value| {
            state.process_response(value);
            glib::Continue(true)
        });

M src/signal.rs => src/signal.rs +9 -18
@@ 1,22 1,12 @@
use enum_variant_type::EnumVariantType;
use futures_util::future::*;
use futures_util::sink::SinkExt;
use futures_util::sink::*;
use futures_util::stream::*;
use futures_util::stream::{select_all, SelectAll};
use futures_util::*;
use futures_util::{future, pin_mut, StreamExt};
use mio::net::TcpStream;
use serde::*;
use futures_util::{future, StreamExt};
use serde::{Deserialize, Serialize};
use std::collections::*;
use std::convert::TryFrom;
use std::rc::*;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::prelude::*;
use tokio::stream::*;
use tokio_tungstenite::tungstenite::protocol::*;
use tokio_tungstenite::*;

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "request")]


@@ 29,7 19,7 @@ pub enum SignalRequest {
    GetChatList,
    GetContactList,
    GetDevices,
    GetMoreMessages { lastId: String },
    GetMoreMessages { last_id: String },
    LeaveChat,
    ToggleNotifications { chat: String },
    CreateNewGroup { name: String, members: Vec<String> },


@@ 44,6 34,7 @@ pub enum SignalResponse {
    ChatList(Vec<Chat>),
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    MessageList(SignalMessageList),
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    ShowMessages(String),
}



@@ 121,11 112,11 @@ pub struct SignalSession<'a> {
    pub stream: BoxStream<'a, SignalResponse>,
}
impl<'a> SignalSession<'a> {
    pub fn from_socket(mut socket: WebSocketStream<tokio::net::TcpStream>) -> SignalSession<'a> {
        let (mut write, mut read) = socket.split();
    pub fn from_socket(socket: WebSocketStream<tokio::net::TcpStream>) -> SignalSession<'a> {
        let (write, read) = socket.split();
        let st = read.filter_map(|x| {
            if let Some(attempt) =
                serde_json::from_str::<SignalResponse>(&x.unwrap().into_text().unwrap()).ok()
            if let Ok(attempt) =
                serde_json::from_str::<SignalResponse>(&x.unwrap().into_text().unwrap())
            {
                return future::ready(Some(attempt));
            }


@@ 151,7 142,7 @@ impl<'a> SignalSession<'a> {
            .stream
            .by_ref()
            .filter_map(|x| {
                if let Some(v) = T::try_from(x).ok() {
                if let Ok(v) = T::try_from(x) {
                    future::ready(Some(v))
                } else {
                    future::ready(None)