2025-08-06 01:15:13 -04:00
|
|
|
use crate::net;
|
2025-12-04 15:20:12 -05:00
|
|
|
use crate::ui::Page;
|
2025-08-06 01:15:13 -04:00
|
|
|
|
2025-07-03 20:57:37 -04:00
|
|
|
use super::db;
|
|
|
|
|
use super::ui;
|
2025-07-22 17:32:48 -04:00
|
|
|
use iced::widget::markdown;
|
2025-07-25 19:03:50 -04:00
|
|
|
use iced::widget::row;
|
2025-07-19 20:42:07 -04:00
|
|
|
use iced::widget::scrollable;
|
2025-07-22 17:32:48 -04:00
|
|
|
use iced::widget::Column;
|
2025-12-05 12:45:45 -05:00
|
|
|
use iced::widget::Text;
|
2025-07-22 17:32:48 -04:00
|
|
|
use iced::Theme;
|
2025-07-03 20:57:37 -04:00
|
|
|
use iced::{
|
|
|
|
|
widget::{button, column, container, text},
|
|
|
|
|
Element,
|
|
|
|
|
};
|
2025-12-05 12:45:45 -05:00
|
|
|
use rss_content;
|
|
|
|
|
use rss_content::Content;
|
|
|
|
|
use ui::Message;
|
2025-07-03 20:57:37 -04:00
|
|
|
|
|
|
|
|
pub fn list_feeds() -> iced::widget::Column<'static, Message> {
|
|
|
|
|
let feeds = db::get_feeds();
|
|
|
|
|
column(
|
|
|
|
|
feeds
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|f| {
|
2025-08-06 01:15:13 -04:00
|
|
|
let n = net::url_network(&f.url);
|
|
|
|
|
let prefix = match n {
|
2025-12-05 12:45:45 -05:00
|
|
|
net::Network::Clearnet => "",
|
|
|
|
|
net::Network::Tor => "Tor: ",
|
|
|
|
|
net::Network::I2P => "I2P: ",
|
|
|
|
|
_ => "",
|
2025-08-06 01:15:13 -04:00
|
|
|
};
|
2025-07-25 19:03:50 -04:00
|
|
|
row!(
|
2025-12-05 12:45:45 -05:00
|
|
|
button(text(prefix.to_owned() + &f.title))
|
|
|
|
|
.on_press(Message::LoadFeed(f.feed_id)),
|
2025-07-25 19:03:50 -04:00
|
|
|
button(text("Remove feed")).on_press(Message::RemoveFeed(f.feed_id))
|
|
|
|
|
)
|
2025-07-03 20:57:37 -04:00
|
|
|
})
|
|
|
|
|
.map(Element::from),
|
|
|
|
|
)
|
|
|
|
|
.align_x(iced::Alignment::Start)
|
|
|
|
|
.spacing(5)
|
2025-07-04 11:38:49 -04:00
|
|
|
.padding(15)
|
2025-07-03 20:57:37 -04:00
|
|
|
}
|
|
|
|
|
|
2026-02-16 11:15:27 -05:00
|
|
|
pub fn list_items(feed_id: i64) -> iced::widget::Column<'static, Message> {
|
2025-07-03 20:57:37 -04:00
|
|
|
let items: Vec<db::FeedItem> = db::get_feed_items(feed_id);
|
|
|
|
|
column(
|
2025-12-05 12:45:45 -05:00
|
|
|
items
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|i| button(text(i.title.clone())).on_press(Message::LoadItem(i.item_id)))
|
|
|
|
|
.map(Element::from),
|
2025-07-03 20:57:37 -04:00
|
|
|
)
|
|
|
|
|
.align_x(iced::Alignment::Start)
|
|
|
|
|
.spacing(5)
|
2025-07-04 11:38:49 -04:00
|
|
|
.padding(15)
|
2025-07-19 20:42:07 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-07 04:03:38 -04:00
|
|
|
pub fn content_area(content: &'_ Vec<Content>) -> iced::widget::Container<'_, Message> {
|
2025-07-22 17:32:48 -04:00
|
|
|
let mut children: Vec<Element<Message>> = Vec::new();
|
|
|
|
|
for c in content {
|
2025-12-05 12:45:45 -05:00
|
|
|
match c {
|
|
|
|
|
Content::MarkdownParsed(p) => {
|
|
|
|
|
children.push(markdown(p, Theme::Dark).map(Message::LinkClicked));
|
2025-07-22 17:32:48 -04:00
|
|
|
}
|
2025-12-05 12:45:45 -05:00
|
|
|
Content::Image(_) => {
|
|
|
|
|
children.push(text("<Image goes here>").size(32).into());
|
|
|
|
|
}
|
|
|
|
|
Content::Audio(_) => {
|
|
|
|
|
children.push(text("<Audio widget here>").size(32).into());
|
|
|
|
|
}
|
|
|
|
|
Content::Video(_) => {
|
|
|
|
|
children.push(text("<Video goes here>").size(32).into());
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
container(Column::with_children(children).spacing(5))
|
2025-07-19 20:42:07 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-07 04:03:38 -04:00
|
|
|
pub fn media_view(state: &'_ ui::State) -> Element<'_, Message> {
|
2025-07-23 12:38:05 -04:00
|
|
|
match state.current_item.clone().unwrap().media {
|
|
|
|
|
Some(m) => {
|
2025-12-05 12:45:45 -05:00
|
|
|
if m.len() > 0 {
|
|
|
|
|
text(format!("<Media is available:{}>", m)).into()
|
|
|
|
|
} else {
|
2025-07-23 22:00:31 -04:00
|
|
|
text("".to_owned()).into()
|
|
|
|
|
}
|
2025-07-23 12:38:05 -04:00
|
|
|
}
|
2025-12-05 12:45:45 -05:00
|
|
|
None => text("".to_owned()).into(),
|
2025-07-23 12:38:05 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-05 12:45:45 -05:00
|
|
|
pub fn navbar(state: &ui::State) -> Element<Message> {
|
2025-12-04 22:36:36 -05:00
|
|
|
match state.page {
|
2025-12-05 12:45:45 -05:00
|
|
|
Page::Home => row::Row::new()
|
|
|
|
|
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
2025-12-04 22:56:33 -05:00
|
|
|
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
2025-12-05 12:45:45 -05:00
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::Feeds => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
2025-12-04 22:56:33 -05:00
|
|
|
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
2025-12-05 12:45:45 -05:00
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::FeedView => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
|
|
|
|
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
|
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::AllItems => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
|
|
|
|
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
|
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::CategoryView => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
|
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::Testing => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
Page::ItemView => row::Row::new()
|
|
|
|
|
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
|
|
|
|
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
|
|
|
|
|
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
|
|
|
|
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
|
|
|
|
|
.spacing(5)
|
|
|
|
|
.padding(5),
|
|
|
|
|
}
|
|
|
|
|
.into()
|
2025-12-04 15:20:12 -05:00
|
|
|
}
|
|
|
|
|
|
2026-02-16 11:15:27 -05:00
|
|
|
pub fn list_item(id: i64, title: String, description: String) -> Column<'static, Message> {
|
2025-12-04 15:20:12 -05:00
|
|
|
Column::new()
|
2025-12-05 12:45:45 -05:00
|
|
|
.push(button(Text::new(title)).on_press(Message::LoadItem(id)))
|
|
|
|
|
.push(text(description))
|
|
|
|
|
.align_x(iced::Alignment::Center)
|
|
|
|
|
.spacing(5)
|
2025-12-04 15:20:12 -05:00
|
|
|
}
|
|
|
|
|
|
2025-09-07 04:03:38 -04:00
|
|
|
pub fn content_view(state: &'_ ui::State) -> iced::widget::Scrollable<'_, Message> {
|
2025-07-22 17:32:48 -04:00
|
|
|
let item = state.current_item.clone().unwrap();
|
2025-07-19 20:42:07 -04:00
|
|
|
|
2025-12-05 12:45:45 -05:00
|
|
|
scrollable(column!(
|
|
|
|
|
match item.description {
|
|
|
|
|
Some(_d) => {
|
|
|
|
|
content_area(&state.item_description)
|
|
|
|
|
}
|
|
|
|
|
None => {
|
|
|
|
|
container(text("No description found"))
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
match item.content {
|
|
|
|
|
Some(_c) => {
|
|
|
|
|
content_area(&state.item_content)
|
|
|
|
|
}
|
|
|
|
|
None => {
|
|
|
|
|
container(text("No content found"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
))
|
|
|
|
|
.width(iced::Fill)
|
|
|
|
|
}
|