Starting to support fancier elements...
This commit is contained in:
parent
56a62e96fd
commit
a4756b8ec4
2 changed files with 109 additions and 81 deletions
135
src/ui.rs
135
src/ui.rs
|
@ -1,17 +1,20 @@
|
|||
use crate::db::FeedItem;
|
||||
use crate::widgets::content_view;
|
||||
|
||||
use super::db;
|
||||
use super::widgets;
|
||||
use iced::widget::markdown::Url;
|
||||
use iced::widget::row;
|
||||
use iced::widget::scrollable;
|
||||
use iced::widget::text_input;
|
||||
use iced::widget::markdown::Url;
|
||||
use iced::Task;
|
||||
use iced::{
|
||||
widget::{button, column, container, text},
|
||||
Element,
|
||||
Length::Fill,
|
||||
};
|
||||
use rss_content::parse_content;
|
||||
use rss_content::Content;
|
||||
|
||||
pub fn user_interface() -> iced::Result {
|
||||
iced::run(update, view)
|
||||
|
@ -26,20 +29,24 @@ pub enum Page {
|
|||
Testing,
|
||||
}
|
||||
|
||||
struct State {
|
||||
pub struct State {
|
||||
page: Page,
|
||||
current_feed: usize,
|
||||
current_item: usize,
|
||||
feed_input: String
|
||||
pub current_item: Option<FeedItem>,
|
||||
pub item_description: Vec<Content>,
|
||||
pub item_content: Vec<Content>,
|
||||
feed_input: String,
|
||||
}
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
State {
|
||||
State {
|
||||
page: Page::Home,
|
||||
current_feed: 0,
|
||||
current_item: 0,
|
||||
feed_input: String::from("")
|
||||
}
|
||||
current_item: None,
|
||||
item_description: Vec::new(),
|
||||
item_content: Vec::new(),
|
||||
feed_input: String::from(""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,15 +56,15 @@ pub enum Message {
|
|||
LoadFeed(usize),
|
||||
AddFeed(String),
|
||||
LoadItem(usize),
|
||||
FieldUpdated(AppField,String),
|
||||
FieldUpdated(AppField, String),
|
||||
LinkClicked(Url),
|
||||
Done(String),
|
||||
ResetDB
|
||||
ResetDB,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AppField {
|
||||
FeedInput
|
||||
FeedInput,
|
||||
}
|
||||
|
||||
async fn add_feed_background(url: String) -> String {
|
||||
|
@ -66,51 +73,58 @@ async fn add_feed_background(url: String) -> String {
|
|||
"Done adding feed".to_string()
|
||||
}
|
||||
|
||||
fn update(state: &mut State, mes: Message) -> Task<Message>{
|
||||
fn update(state: &mut State, mes: Message) -> Task<Message> {
|
||||
match mes {
|
||||
Message::ChangePage(p) => {
|
||||
state.page=p;
|
||||
state.page = p;
|
||||
Task::none()
|
||||
},
|
||||
}
|
||||
Message::LoadFeed(feed_id) => {
|
||||
state.current_feed = feed_id;
|
||||
state.page=Page::FeedView;
|
||||
state.page = Page::FeedView;
|
||||
Task::none()
|
||||
},
|
||||
}
|
||||
Message::AddFeed(f) => {
|
||||
state.feed_input = "".to_string();
|
||||
Task::perform(
|
||||
add_feed_background(f.to_string()),
|
||||
Message::Done
|
||||
)
|
||||
},
|
||||
Task::perform(add_feed_background(f.to_string()), Message::Done)
|
||||
}
|
||||
Message::LinkClicked(l) => {
|
||||
println!("Link clicked: {}",l);
|
||||
println!("Link clicked: {}", l);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
Message::LoadItem(id) => {
|
||||
state.current_item = id;
|
||||
let item = db::get_item(id);
|
||||
state.item_description = match &item.description {
|
||||
Some(d) => {
|
||||
parse_content(&d)
|
||||
}
|
||||
None => Vec::new()
|
||||
};
|
||||
state.item_content = match &item.content{
|
||||
Some(c) => {
|
||||
parse_content(&c)
|
||||
}
|
||||
None => Vec::new()
|
||||
};
|
||||
state.current_item = Some(item);
|
||||
state.page = Page::ItemView;
|
||||
Task::none()
|
||||
}
|
||||
Message::Done(_) => {Task::none()},
|
||||
Message::Done(_) => Task::none(),
|
||||
Message::FieldUpdated(field, value) => {
|
||||
match field {
|
||||
AppField::FeedInput => {
|
||||
state.feed_input=value;
|
||||
state.feed_input = value;
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
},
|
||||
}
|
||||
Message::ResetDB => {
|
||||
db::reset();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
fn view(state: &State) -> Element<'_, Message> {
|
||||
|
@ -125,7 +139,9 @@ fn view(state: &State) -> Element<'_, Message> {
|
|||
|
||||
fn home(_state: &State) -> Element<'_, Message> {
|
||||
container(column!(
|
||||
scrollable(widgets::list_feeds()).width(iced::Fill).height(iced::Fill),
|
||||
scrollable(widgets::list_feeds())
|
||||
.width(iced::Fill)
|
||||
.height(iced::Fill),
|
||||
button("Go to test!").on_press(Message::ChangePage(Page::Testing))
|
||||
))
|
||||
.padding(15)
|
||||
|
@ -134,47 +150,50 @@ fn home(_state: &State) -> Element<'_, Message> {
|
|||
.into()
|
||||
}
|
||||
|
||||
|
||||
fn feed_layout(state: &State) -> Element<'_, Message> {
|
||||
container(
|
||||
column!(
|
||||
button(text("Home")).on_press(Message::ChangePage(Page::Home)),
|
||||
scrollable(widgets::list_items(state.current_feed)).width(iced::Fill).height(iced::Fill),
|
||||
)
|
||||
)
|
||||
.height(Fill)
|
||||
.width(Fill)
|
||||
.into()
|
||||
container(column!(
|
||||
button(text("Home")).on_press(Message::ChangePage(Page::Home)),
|
||||
scrollable(widgets::list_items(state.current_feed))
|
||||
.width(iced::Fill)
|
||||
.height(iced::Fill),
|
||||
))
|
||||
.height(Fill)
|
||||
.width(Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn item_view(state: &State) -> Element<'_, Message> {
|
||||
let item = db::get_item(state.current_item);
|
||||
container(
|
||||
column!(
|
||||
row!(
|
||||
button(text("Home")).on_press(Message::ChangePage(Page::Home)),
|
||||
button(text("Feed")).on_press(Message::ChangePage(Page::FeedView))
|
||||
).spacing(10),
|
||||
content_view(item),
|
||||
container(column!(
|
||||
row!(
|
||||
button(text("Home")).on_press(Message::ChangePage(Page::Home)),
|
||||
button(text("Feed")).on_press(Message::ChangePage(Page::FeedView))
|
||||
)
|
||||
)
|
||||
.height(Fill)
|
||||
.width(Fill)
|
||||
.into()
|
||||
.spacing(10),
|
||||
content_view(state),
|
||||
))
|
||||
.height(Fill)
|
||||
.width(Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn item_list(_: &State) -> Element<'_,Message>{
|
||||
fn item_list(_: &State) -> Element<'_, Message> {
|
||||
todo!()
|
||||
}
|
||||
fn testing(state: &State) -> Element<'_, Message> {
|
||||
column!(
|
||||
text("Dev Panel"),
|
||||
button("Add gabe.rocks").on_press(Message::AddFeed(String::from("https://gabe.rocks/rss"))),
|
||||
button("Add LSN").on_press(Message::AddFeed(String::from("https://libresolutions.network/rss"))),
|
||||
button("Add LSN").on_press(Message::AddFeed(String::from(
|
||||
"https://libresolutions.network/rss"
|
||||
))),
|
||||
row!(
|
||||
text_input("Add a feed",&state.feed_input).on_input(|val| Message::FieldUpdated(AppField::FeedInput,val)).width(300),
|
||||
text_input("Add a feed", &state.feed_input)
|
||||
.on_input(|val| Message::FieldUpdated(AppField::FeedInput, val))
|
||||
.width(300),
|
||||
button("Add feed!").on_press(Message::AddFeed(state.feed_input.clone()))
|
||||
).spacing(5).padding(10),
|
||||
)
|
||||
.spacing(5)
|
||||
.padding(10),
|
||||
button("Wipe DB").on_press(Message::ResetDB),
|
||||
button("go back!").on_press(Message::ChangePage(Page::Home))
|
||||
)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::db::FeedItem;
|
||||
|
||||
use super::db;
|
||||
use super::ui;
|
||||
use iced::widget::markdown;
|
||||
use iced::widget::scrollable;
|
||||
use iced::widget::Column;
|
||||
use iced::Theme;
|
||||
use rss_content::Content;
|
||||
use ui::Message;
|
||||
use rss_content;
|
||||
|
@ -40,44 +41,52 @@ pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
|
|||
.padding(15)
|
||||
}
|
||||
|
||||
pub fn content_area(cnt: String) -> iced::widget::Container<'static,Message>{
|
||||
let content = rss_content::parse_content(&cnt);
|
||||
container(
|
||||
column(
|
||||
content.into_iter().map(|c: Content|{
|
||||
match c {
|
||||
Content::Markdown(md) => {
|
||||
text(md)
|
||||
},
|
||||
Content::Image(_) => {text("Image goes here")},
|
||||
Content::Audio(_) => {text("Audio widget here")},
|
||||
Content::Video(_) => {text("video player here")},
|
||||
_ => {text("")}
|
||||
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());},
|
||||
_ => {}
|
||||
}
|
||||
}).map(Element::from)
|
||||
)
|
||||
}
|
||||
container(
|
||||
Column::with_children(children)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
pub fn content_view(item: FeedItem) -> iced::widget::Scrollable<'static, Message> {
|
||||
pub fn content_view(state: &super::ui::State) -> iced::widget::Scrollable<Message> {
|
||||
let item = state.current_item.clone().unwrap();
|
||||
|
||||
scrollable(
|
||||
column!(
|
||||
text(item.title).size(34),
|
||||
match item.description {
|
||||
Some(d) => {
|
||||
content_area(d)
|
||||
Some(_d) => {
|
||||
content_area(&state.item_description)
|
||||
},
|
||||
None => {container(text("No description found"))}
|
||||
},
|
||||
match item.content {
|
||||
Some(c) => {
|
||||
content_area(c)
|
||||
Some(_c) => {
|
||||
content_area(&state.item_content)
|
||||
}
|
||||
None => {container(text("No content found"))}
|
||||
}
|
||||
|
||||
)
|
||||
)
|
||||
).width(iced::Fill)
|
||||
}
|
Loading…
Reference in a new issue