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:
Skylar Hill 2024-03-10 22:49:09 -05:00
commit f105b849d2
4 changed files with 1345 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1168
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

9
Cargo.toml Normal file
View File

@ -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"

167
src/main.rs Normal file
View File

@ -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),
},
]);
}