Date parsing works now!
This commit is contained in:
parent
b37c73cf14
commit
60fd547a6d
3 changed files with 152 additions and 117 deletions
29
src/db.rs
29
src/db.rs
|
|
@ -169,6 +169,13 @@ pub fn remove_feed(feed_id: usize) {
|
|||
}
|
||||
}
|
||||
|
||||
fn modify_date(s: &str) -> Option<String> {
|
||||
match DateTime::parse_from_rfc2822(s){
|
||||
Ok(t) => {Some(t.to_rfc3339())}
|
||||
Err(_) => None
|
||||
}
|
||||
|
||||
}
|
||||
pub fn store_items(feed: rss::Channel, feed_id: usize) {
|
||||
let conn = Connection::open(get_db_path()).unwrap();
|
||||
feed.items.into_iter().for_each(|i: rss::Item| {
|
||||
|
|
@ -185,11 +192,23 @@ pub fn store_items(feed: rss::Channel, feed_id: usize) {
|
|||
values(?1,?2,?3,?4,?5,?6,?7,?8)",
|
||||
[
|
||||
i.link,
|
||||
i.title,
|
||||
i.description,
|
||||
i.content,
|
||||
match i.title {
|
||||
Some(t) => Some(t.clone()),
|
||||
None => None
|
||||
},
|
||||
match i.description {
|
||||
Some(d) => Some(d.clone()),
|
||||
None => None
|
||||
},
|
||||
match i.content {
|
||||
Some(c) => {Some(c.clone())},
|
||||
None => {None}
|
||||
},
|
||||
Some(feed_id.to_string()),
|
||||
i.pub_date.clone(),
|
||||
match i.pub_date {
|
||||
Some(s) => {modify_date(&s)},
|
||||
None => {None}
|
||||
},
|
||||
{
|
||||
match t.enclosure() {
|
||||
Some(e) => Some(e.url().to_owned()),
|
||||
|
|
@ -237,7 +256,7 @@ fn row2feed_item(row: &Row) -> FeedItem{
|
|||
|
||||
pub fn get_all_items() -> Vec<FeedItem> {
|
||||
let conn = get_db();
|
||||
let mut stmt = conn.prepare("select itemID,title,url,date,media,description,content from items").unwrap();
|
||||
let mut stmt = conn.prepare("select itemID,title,url,date,media,description,content from items order by date desc limit 50 ").unwrap();
|
||||
let items: Result<Vec<FeedItem>> = stmt.query_map([],|row| {
|
||||
Ok(row2feed_item(row))
|
||||
}).unwrap().collect();
|
||||
|
|
|
|||
26
src/ui.rs
26
src/ui.rs
|
|
@ -33,6 +33,7 @@ pub fn user_interface() -> iced::Result {
|
|||
#[derive(Clone, Debug,PartialEq)]
|
||||
pub enum Page {
|
||||
Home,
|
||||
Feeds,
|
||||
FeedView,
|
||||
AllItems,
|
||||
ItemView,
|
||||
|
|
@ -151,6 +152,7 @@ fn update(state: &mut State, mes: Message) -> Task<Message> {
|
|||
fn view(state: &State) -> Element<'_, Message> {
|
||||
match state.page {
|
||||
Page::Home => home(&state),
|
||||
Page::Feeds => feeds(&state),
|
||||
Page::FeedView => feed_layout(&state),
|
||||
Page::AllItems => item_list(&state),
|
||||
Page::ItemView => item_view(&state),
|
||||
|
|
@ -162,10 +164,7 @@ fn view(state: &State) -> Element<'_, Message> {
|
|||
fn home(state: &State) -> Element<'_, Message> {
|
||||
container(column!(
|
||||
widgets::navbar(state),
|
||||
scrollable(widgets::list_feeds())
|
||||
.width(iced::Fill)
|
||||
.height(iced::Fill),
|
||||
button("Go to test!").on_press(Message::ChangePage(Page::Testing))
|
||||
text("RSSCar: RSS Crawler-aided reader.")
|
||||
))
|
||||
.padding(0)
|
||||
.height(Fill)
|
||||
|
|
@ -173,6 +172,18 @@ fn home(state: &State) -> Element<'_, Message> {
|
|||
.into()
|
||||
}
|
||||
|
||||
fn feeds(state: &State) -> Element<'_,Message> {
|
||||
container(
|
||||
column!(
|
||||
navbar(state),
|
||||
scrollable(widgets::list_feeds())
|
||||
.width(iced::Fill)
|
||||
.height(iced::Fill)
|
||||
)
|
||||
).width(iced::Fill)
|
||||
.height(iced::Fill).into()
|
||||
}
|
||||
|
||||
fn feed_layout(state: &State) -> Element<'_, Message> {
|
||||
container(column!(
|
||||
widgets::navbar(state),
|
||||
|
|
@ -209,10 +220,9 @@ fn item_list(state: &State) -> Element<'_, Message> {
|
|||
db::get_all_items().iter().map(|i|{
|
||||
widgets::list_item(i.item_id, i.title.clone(), i.description.clone().unwrap_or("".to_owned()))
|
||||
}).map(iced::Element::from)
|
||||
).align_x(iced::Alignment::Center)).width(Fill).spacing(5)
|
||||
),
|
||||
|
||||
).width(Fill).height(Fill).into()
|
||||
).align_x(iced::Alignment::Center).width(Fill)).width(Fill).spacing(5)
|
||||
),
|
||||
).width(Fill).height(Fill).align_x(iced::Alignment::Center).into()
|
||||
}
|
||||
|
||||
fn category_view(state: &State) -> Element<'_,Message> {
|
||||
|
|
|
|||
214
src/widgets.rs
214
src/widgets.rs
|
|
@ -3,19 +3,19 @@ use crate::ui::Page;
|
|||
|
||||
use super::db;
|
||||
use super::ui;
|
||||
use iced::widget::Text;
|
||||
use iced::widget::markdown;
|
||||
use iced::widget::row;
|
||||
use iced::widget::scrollable;
|
||||
use iced::widget::Column;
|
||||
use iced::widget::Text;
|
||||
use iced::Theme;
|
||||
use rss_content::Content;
|
||||
use ui::Message;
|
||||
use rss_content;
|
||||
use iced::{
|
||||
widget::{button, column, container, text},
|
||||
Element,
|
||||
};
|
||||
use rss_content;
|
||||
use rss_content::Content;
|
||||
use ui::Message;
|
||||
|
||||
pub fn list_feeds() -> iced::widget::Column<'static, Message> {
|
||||
let feeds = db::get_feeds();
|
||||
|
|
@ -25,13 +25,14 @@ pub fn list_feeds() -> iced::widget::Column<'static, Message> {
|
|||
.map(|f| {
|
||||
let n = net::url_network(&f.url);
|
||||
let prefix = match n {
|
||||
net::Network::Clearnet => {""}
|
||||
net::Network::Tor => {"Tor: "}
|
||||
net::Network::I2P => {"I2P: "}
|
||||
_ => {""}
|
||||
net::Network::Clearnet => "",
|
||||
net::Network::Tor => "Tor: ",
|
||||
net::Network::I2P => "I2P: ",
|
||||
_ => "",
|
||||
};
|
||||
row!(
|
||||
button(text(prefix.to_owned() + &f.title)).on_press(Message::LoadFeed(f.feed_id)),
|
||||
button(text(prefix.to_owned() + &f.title))
|
||||
.on_press(Message::LoadFeed(f.feed_id)),
|
||||
button(text("Remove feed")).on_press(Message::RemoveFeed(f.feed_id))
|
||||
)
|
||||
})
|
||||
|
|
@ -42,14 +43,13 @@ pub fn list_feeds() -> iced::widget::Column<'static, Message> {
|
|||
.padding(15)
|
||||
}
|
||||
|
||||
pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
|
||||
pub fn list_items(feed_id: usize) -> iced::widget::Column<'static, Message> {
|
||||
let items: Vec<db::FeedItem> = db::get_feed_items(feed_id);
|
||||
column(
|
||||
items.iter()
|
||||
.map(|i| {
|
||||
button(text(i.title.clone())).on_press(Message::LoadItem(i.item_id))
|
||||
})
|
||||
.map(Element::from),
|
||||
items
|
||||
.iter()
|
||||
.map(|i| button(text(i.title.clone())).on_press(Message::LoadItem(i.item_id)))
|
||||
.map(Element::from),
|
||||
)
|
||||
.align_x(iced::Alignment::Start)
|
||||
.spacing(5)
|
||||
|
|
@ -59,115 +59,121 @@ pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
|
|||
pub fn content_area(content: &'_ Vec<Content>) -> iced::widget::Container<'_, Message> {
|
||||
let mut children: Vec<Element<Message>> = Vec::new();
|
||||
for c in content {
|
||||
match c {
|
||||
Content::MarkdownParsed(p) => {
|
||||
children.push(
|
||||
markdown(p, Theme::Dark).map(Message::LinkClicked)
|
||||
);
|
||||
}
|
||||
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());},
|
||||
_ => {}
|
||||
}
|
||||
match c {
|
||||
Content::MarkdownParsed(p) => {
|
||||
children.push(markdown(p, Theme::Dark).map(Message::LinkClicked));
|
||||
}
|
||||
container(
|
||||
Column::with_children(children).spacing(5)
|
||||
)
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
pub fn media_view(state: &'_ ui::State) -> Element<'_, Message> {
|
||||
match state.current_item.clone().unwrap().media {
|
||||
Some(m) => {
|
||||
if m.len() > 0{
|
||||
text(format!("<Media is available:{}>",m)).into()
|
||||
}
|
||||
else {
|
||||
if m.len() > 0 {
|
||||
text(format!("<Media is available:{}>", m)).into()
|
||||
} else {
|
||||
text("".to_owned()).into()
|
||||
|
||||
}
|
||||
}
|
||||
None => {
|
||||
text("".to_owned()).into()
|
||||
}
|
||||
None => text("".to_owned()).into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn navbar (state: &ui::State) -> Element<Message>{
|
||||
pub fn navbar(state: &ui::State) -> Element<Message> {
|
||||
match state.page {
|
||||
Page::Home => {
|
||||
row::Row::new().push(
|
||||
button("All Items").on_press(Message::ChangePage(Page::AllItems))
|
||||
).push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
|
||||
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)))
|
||||
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
|
||||
.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))
|
||||
)
|
||||
.spacing(5).padding(5)
|
||||
},
|
||||
Page::AllItems => {
|
||||
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
||||
.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)))
|
||||
.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("All Items").on_press(Message::ChangePage(Page::AllItems))
|
||||
)
|
||||
.spacing(5).padding(5)}
|
||||
Page::Testing => {
|
||||
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
|
||||
.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("All Items").on_press(Message::ChangePage(Page::AllItems))
|
||||
)
|
||||
.spacing(5).padding(5)}
|
||||
}.into()
|
||||
|
||||
.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()
|
||||
}
|
||||
|
||||
pub fn list_item(id: usize,title: String, description: String) -> Column<'static,Message>{
|
||||
pub fn list_item(id: usize, title: String, description: String) -> Column<'static, Message> {
|
||||
Column::new()
|
||||
.push(button(Text::new(title)).on_press(Message::LoadItem(id)))
|
||||
.push(text(description))
|
||||
.align_x(iced::Alignment::Center)
|
||||
.spacing(5)
|
||||
.push(button(Text::new(title)).on_press(Message::LoadItem(id)))
|
||||
.push(text(description))
|
||||
.align_x(iced::Alignment::Center)
|
||||
.spacing(5)
|
||||
}
|
||||
|
||||
pub fn content_view(state: &'_ ui::State) -> iced::widget::Scrollable<'_, Message> {
|
||||
let item = state.current_item.clone().unwrap();
|
||||
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue