Initial commit
A very, very basic setup that lets you input messages and have them appear in the chat log
This commit is contained in:
commit
f105b849d2
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "pluralchat"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
relm4 = "0.6.2"
|
||||||
|
relm4-components = "0.6.2"
|
||||||
|
relm4-macros = "0.6.2"
|
|
@ -0,0 +1,167 @@
|
||||||
|
use gtk::pango::AttrList;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use relm4::factory::FactoryVecDeque;
|
||||||
|
use relm4::prelude::*;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct User {
|
||||||
|
uuid: u32,
|
||||||
|
name: String,
|
||||||
|
pfp: Option<gtk::gdk::Texture>,
|
||||||
|
bio: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Message {
|
||||||
|
mid: u32,
|
||||||
|
sender: Rc<User>,
|
||||||
|
content: String,
|
||||||
|
reply_to: Option<Box<Message>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::factory]
|
||||||
|
impl FactoryComponent for Message {
|
||||||
|
type Init = Message;
|
||||||
|
type Input = ();
|
||||||
|
type Output = ();
|
||||||
|
type Widgets = MessageWidgets;
|
||||||
|
type CommandOutput = ();
|
||||||
|
type ParentWidget = gtk::Box;
|
||||||
|
type ParentInput = ChatPaneInput;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_spacing: 5,
|
||||||
|
set_margin_start: 5,
|
||||||
|
set_margin_end: 5,
|
||||||
|
gtk::Label {
|
||||||
|
set_label: &self.sender.name,
|
||||||
|
set_attributes: Some(&AttrList::from_string("0 -1 weight bold").unwrap())
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
set_margin_start: 5,
|
||||||
|
set_label: &self.content,
|
||||||
|
set_wrap: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn init_model(init: Self::Init, _index: &Self::Index, _sender: FactorySender<Self>) -> Self {
|
||||||
|
init
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChatPane {
|
||||||
|
messages: FactoryVecDeque<Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum ChatPaneInput {
|
||||||
|
NewMessage(Message),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component]
|
||||||
|
impl SimpleComponent for ChatPane {
|
||||||
|
type Init = Vec<Message>;
|
||||||
|
type Input = ChatPaneInput;
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Window::builder()
|
||||||
|
.title("PluralChat")
|
||||||
|
.default_height(900)
|
||||||
|
.default_width(800)
|
||||||
|
.build() {
|
||||||
|
#[local_ref]
|
||||||
|
message_list -> gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 5,
|
||||||
|
gtk::Box {
|
||||||
|
gtk::Text {
|
||||||
|
connect_activate[sender] => move |txt| {
|
||||||
|
sender.input(Self::Input::NewMessage(Message {
|
||||||
|
content: txt.text().to_string(),
|
||||||
|
mid: 2,
|
||||||
|
reply_to: None,
|
||||||
|
sender: Rc::new(User {
|
||||||
|
bio: String::from("aaa"),
|
||||||
|
name: String::from("Foo Bar, esq."),
|
||||||
|
uuid: 9,
|
||||||
|
pfp: None
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
txt.set_text("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||||
|
match message {
|
||||||
|
Self::Input::NewMessage(msg) => {
|
||||||
|
let mut guard = (*self).messages.guard();
|
||||||
|
guard.push_back(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: &Self::Root,
|
||||||
|
sender: ComponentSender<Self>,
|
||||||
|
) -> ComponentParts<Self> {
|
||||||
|
let mut messages = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||||
|
{
|
||||||
|
let mut message_guard = messages.guard();
|
||||||
|
for msg in init {
|
||||||
|
message_guard.push_back(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = ChatPane { messages };
|
||||||
|
|
||||||
|
let message_list = model.messages.widget();
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let app = RelmApp::new("me.skylarhill.pluralchat");
|
||||||
|
let test_user = Rc::new(User {
|
||||||
|
bio: String::from("I'm not real"),
|
||||||
|
pfp: None,
|
||||||
|
name: String::from("Fakey McFakerton"),
|
||||||
|
uuid: 1,
|
||||||
|
});
|
||||||
|
app.run::<ChatPane>(vec![
|
||||||
|
Message {
|
||||||
|
content: String::from("una"),
|
||||||
|
mid: 1,
|
||||||
|
reply_to: None,
|
||||||
|
sender: Rc::clone(&test_user),
|
||||||
|
},
|
||||||
|
Message {
|
||||||
|
content: String::from("dos"),
|
||||||
|
mid: 1,
|
||||||
|
reply_to: None,
|
||||||
|
sender: Rc::clone(&test_user),
|
||||||
|
},
|
||||||
|
Message {
|
||||||
|
content: String::from("threes"),
|
||||||
|
mid: 1,
|
||||||
|
reply_to: None,
|
||||||
|
sender: Rc::clone(&test_user),
|
||||||
|
},
|
||||||
|
Message {
|
||||||
|
content: String::from("quatter"),
|
||||||
|
mid: 1,
|
||||||
|
reply_to: None,
|
||||||
|
sender: Rc::clone(&test_user),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
Loading…
Reference in New Issue