init: first commit

This commit is contained in:
Louis Dalibard 2024-04-20 22:21:47 +02:00
commit 1a3f0f4d1b
5 changed files with 1985 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1797
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

29
Cargo.toml Normal file
View File

@ -0,0 +1,29 @@
[package]
name = "peiji"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["macros", "gnome_42"]
libadwaita = ["adw"]
libpanel = ["panel"]
macros = ["relm4-macros"]
gnome_46 = ["gnome_45", "gtk/gnome_45", "adw/v1_5"]
gnome_45 = ["gnome_44", "gtk/gnome_45", "adw/v1_4"]
gnome_44 = ["gnome_43", "gtk/gnome_44", "adw/v1_3"]
gnome_43 = ["gnome_42", "gtk/gnome_43", "adw/v1_2"]
gnome_42 = ["gtk/gnome_42"]
# All features except docs. This is also used in the CI
all = ["macros", "libadwaita", "panel", "panel/v1_4"]
[dependencies]
adw = { version = "0.6", optional = true, package = "libadwaita" }
epub = "2.1.1"
gtk = { version = "0.8.1", package = "gtk4" }
relm4 = "0.8.1"
scraper = "0.19.0"
panel = { version = "0.4", optional = true, package = "libpanel" }
relm4-macros = { version = "0.8.1", optional = true }

158
src/main.rs Normal file
View File

@ -0,0 +1,158 @@
use std::{env, path::Path, process::exit};
use epub::doc::EpubDoc;
use gtk::glib::clone;
use gtk::prelude::*;
use relm4::prelude::*;
use scraper::{Html, Selector};
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Please provide an ePub file to read. Usage: peiji <file.epub>");
exit(1)
}
let app = RelmApp::new("dev.ontake.peiji").with_args(vec![args[1].to_string()]);
app.run::<App>(0);
}
struct App {
page_num: u8,
page_string: String,
doc: EpubDoc<std::io::BufReader<std::fs::File>>,
}
#[derive(Debug)]
enum Msg {
PageNext,
PagePrev,
}
struct AppWidgets {
// window: gtk::Window,
// vbox: gtk::Box,
// inc_button: gtk::Button,
// dec_button: gtk::Button,
page_num_lbl: gtk::Label,
text_buffer: gtk::TextBuffer,
page_string_textview: gtk::TextView,
}
impl SimpleComponent for App {
type Init = u8;
type Input = Msg;
type Output = ();
type Widgets = AppWidgets;
type Root = gtk::Window;
fn init_root() -> Self::Root {
gtk::Window::builder()
.title("peiji")
.default_width(300)
.default_height(100)
.build()
}
// Initialize the component.
fn init(
page_num: Self::Init,
window: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let args: Vec<String> = env::args().collect();
let path = Path::new(&args[1]);
println!("{:#?}", path);
let doc = EpubDoc::new(path);
let doc = doc.unwrap();
let page_string = "".into();
let model = App {
page_num,
page_string,
doc,
};
let vbox = gtk::Box::builder()
.orientation(gtk::Orientation::Vertical)
.spacing(5)
.build();
let hbox = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.spacing(5)
.build();
let inc_button = gtk::Button::with_label(">");
let dec_button = gtk::Button::with_label("<");
let page_num_lbl = gtk::Label::new(Some(&format!("Page {}", model.page_num)));
page_num_lbl.set_margin_all(5);
let text_buffer = gtk::TextBuffer::default();
text_buffer.set_text(&model.page_string);
let page_string_textview = gtk::TextView::with_buffer(&text_buffer);
page_string_textview.set_margin_all(5);
page_string_textview.set_wrap_mode(gtk::WrapMode::Word);
let scrolled_window = gtk::ScrolledWindow::default();
scrolled_window.set_child(Some(&vbox));
window.set_child(Some(&scrolled_window));
vbox.set_margin_all(5);
hbox.append(&dec_button);
hbox.append(&inc_button);
hbox.append(&page_num_lbl);
vbox.append(&hbox);
vbox.append(&page_string_textview);
vbox.set_hexpand(false);
vbox.set_vexpand(false);
inc_button.connect_clicked(clone!(@strong sender => move |_| {
sender.input(Msg::PageNext);
}));
dec_button.connect_clicked(clone!(@strong sender => move |_| {
sender.input(Msg::PagePrev);
}));
let widgets = AppWidgets {
page_num_lbl,
text_buffer,
page_string_textview,
};
ComponentParts { model, widgets }
}
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
match msg {
Msg::PageNext => {
self.page_num = self.page_num.wrapping_add(1);
}
Msg::PagePrev => {
self.page_num = self.page_num.wrapping_sub(1);
}
}
self.doc.set_current_page(self.page_num.into());
let html = self.doc.get_current_str().unwrap().0;
let document = Html::parse_document(html.as_str());
let selector = Selector::parse("body").unwrap();
let body = document.select(&selector).next().unwrap();
let text = body.text().collect::<Vec<_>>();
let joined_text = text.join("\n");
println!("{}", joined_text);
self.page_string = joined_text;
}
// Update the view to represent the updated model.
fn update_view(&self, widgets: &mut Self::Widgets, _sender: ComponentSender<Self>) {
widgets
.page_num_lbl
.set_label(&format!("Page {}", self.page_num));
widgets.text_buffer.set_text(&self.page_string);
widgets
.page_string_textview
.set_buffer(Some(&widgets.text_buffer));
}
}

BIN
test.epub Normal file

Binary file not shown.