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