Skip to content

Commit

Permalink
Sort comments (#10)
Browse files Browse the repository at this point in the history
* local recursive sort for comments and ui for #9

* add hot rank sorting for comments
* add old sort for posts
  • Loading branch information
LunaticHacker authored Dec 8, 2021
1 parent 1c24026 commit e3e3066
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 77 deletions.
43 changes: 43 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ serde_json = "1.0"
directories = "3.0.2"
toml = "0.5.8"
rpassword = "5.0.1"
chrono = "0.4"

[patch.crates-io]
tui = {git = "https://github.com/LunaticHacker/tui-rs", branch = "for-ltv"}
30 changes: 9 additions & 21 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ pub struct Comment {
pub id: i32,
pub content: String,
pub parent_id: Option<i32>,
pub published: String,
}

#[derive(Deserialize, Default, Clone)]
pub struct CommentInfo {
pub comment: Option<Comment>,
pub comment: Comment,
pub creator: Creator,
pub counts: CommentCounts,
//There are more fields but we don't care
}

Expand All @@ -71,19 +73,7 @@ impl CommentTree {
fn fill_children(mut self, comments: &Vec<CommentInfo>) -> Self {
for i in 0..comments.len() {
let clone = comments.clone();
if comments[i]
.comment
.as_ref()
.unwrap_or(&Comment::default())
.parent_id
.unwrap_or_default()
== self
.comment
.comment
.as_ref()
.unwrap_or(&Comment::default())
.id
{
if comments[i].comment.parent_id.unwrap_or_default() == self.comment.comment.id {
self.children
.push(CommentTree::new(&comments[i]).fill_children(&clone));
}
Expand Down Expand Up @@ -120,6 +110,10 @@ pub struct Community {
pub struct PostCounts {
pub comments: i64,
}
#[derive(Deserialize, Default, Clone)]
pub struct CommentCounts {
pub score: i64,
}
//Api Fetching Functions

pub fn get_posts(url: String, auth: &str, config: &str) -> Result<Vec<PostInfo>, reqwest::Error> {
Expand All @@ -142,13 +136,7 @@ pub fn get_comments(url: String, auth: &str) -> Result<Vec<CommentTree>, reqwest
let clone = comments.clone();
let filtered_comments: Vec<CommentInfo> = comments
.into_iter()
.filter(|c| {
!c.comment
.as_ref()
.unwrap_or(&Comment::default())
.parent_id
.is_some()
})
.filter(|c| !c.comment.parent_id.is_some())
.collect();
let result = utils::map_tree(filtered_comments);
//result.iter().map(|r|r.fill_children(&clone)).collect()
Expand Down
1 change: 1 addition & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum Event<I> {

/// A small event handler that wrap termion input and tick events. Each event
/// type is handled in its own thread and returned to a common `Receiver`
#[allow(dead_code)]
pub struct Events {
rx: mpsc::Receiver<Event<Key>>,
input_handle: thread::JoinHandle<()>,
Expand Down
30 changes: 30 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ fn main() -> Result<(), io::Error> {
&format!("&limit={}&type_={}&sort=New", limit, type_),
)
.unwrap_or_default();
app.unselect();
} else if let Key::Char('2') = input {
//unwrap is fine we will have a config always
let limit = conf.params.get("limit").unwrap();
Expand All @@ -132,6 +133,7 @@ fn main() -> Result<(), io::Error> {
&format!("&limit={}&type_={}&sort=Hot", limit, type_),
)
.unwrap_or_default();
app.unselect();
} else if let Key::Char('3') = input {
//unwrap is fine we will have a config always
let limit = conf.params.get("limit").unwrap();
Expand All @@ -142,6 +144,19 @@ fn main() -> Result<(), io::Error> {
&format!("&limit={}&type_={}&sort=Active", limit, type_),
)
.unwrap_or_default();
app.unselect();
} else if let Key::Char('4') = input {
//unwrap is fine we will have a config always
let limit = conf.params.get("limit").unwrap();
let type_ = conf.params.get("type_").unwrap();
app.posts = api::get_posts(
format!("{}/api/v3/post/list?", &app.instance),
&app.auth,
&format!("&limit={}&type_={}&sort=New", limit, type_),
)
.unwrap_or_default();
app.posts.reverse();
app.unselect();
}
} else if let InputMode::Editing = &app.input_mode {
if let Key::Left = input {
Expand Down Expand Up @@ -234,6 +249,21 @@ fn main() -> Result<(), io::Error> {
}
}
}
} else if let Key::Char('1') = input {
if app.replies.is_empty() {
utils::sort(utils::SortType::New, &mut app.comments);
app.c_unselect()
}
} else if let Key::Char('2') = input {
if app.replies.is_empty() {
utils::sort(utils::SortType::Old, &mut app.comments);
app.c_unselect()
}
} else if let Key::Char('3') = input {
if app.replies.is_empty() {
utils::sort(utils::SortType::Hot, &mut app.comments);
app.c_unselect()
}
} else if let Key::Char('q') = input {
break 'outer;
}
Expand Down
126 changes: 70 additions & 56 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ where
{
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(3), Constraint::Length(7)].as_ref())
.constraints(
[
Constraint::Length(3),
Constraint::Length(1),
Constraint::Length(7),
]
.as_ref(),
)
.split(frame.size());
let input_block = Paragraph::new(tui::text::Text::from(app.input.clone()))
.style(match app.input_mode {
Expand Down Expand Up @@ -77,7 +84,14 @@ where
.highlight_symbol(tui::symbols::line::VERTICAL)
.repeat_highlight_symbol(true);

frame.render_stateful_widget(list, chunks[1], &mut app.state);
frame.render_stateful_widget(list, chunks[2], &mut app.state);

let sort_text = Paragraph::new(" New[1] Hot[2] Active[3] Old[4]").style(
Style::default()
.fg(*app.theme.get(PRIMARY).unwrap())
.bg(*app.theme.get(BG).unwrap()),
);
frame.render_widget(sort_text, chunks[1]);
}
//renders the ui when InputMode is PostView
pub fn draw_post<B>(app: &mut LApp, frame: &mut Frame<B>)
Expand Down Expand Up @@ -169,37 +183,34 @@ where
{
let mut items = vec![];
for comment in &app.comments {
//Comment can be null :(
if let Some(c) = comment.comment.comment.as_ref() {
let mut t = WrappedText::new(frame.size().width - 10);
t.extend(Text::from(vec![
Spans::from(vec![Span::styled(
&comment.comment.creator.name,
Style::default()
.fg(*app.theme.get(SECONDARY).unwrap())
.bg(*app.theme.get(BG).unwrap())
.add_modifier(Modifier::UNDERLINED),
)]),
Spans::from(c.content.as_ref()),
Spans::from(vec![
Span::styled(
format!("{}", comment.children.len()),
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
Span::styled(
" Replies",
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
]),
Spans::from(""),
]));
items.push(ListItem::new(t))
}
let mut t = WrappedText::new(frame.size().width - 10);
t.extend(Text::from(vec![
Spans::from(vec![Span::styled(
&comment.comment.creator.name,
Style::default()
.fg(*app.theme.get(SECONDARY).unwrap())
.bg(*app.theme.get(BG).unwrap())
.add_modifier(Modifier::UNDERLINED),
)]),
Spans::from(comment.comment.comment.content.as_ref()),
Spans::from(vec![
Span::styled(
format!("{}", comment.children.len()),
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
Span::styled(
" Replies",
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
]),
Spans::from(""),
]));
items.push(ListItem::new(t))
}
if let (_, true) = (&app.comments, app.replies.is_empty()) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Percentage(100)])
.constraints([Constraint::Length(1), Constraint::Length(7)])
.split(frame.size());
let list = List::new(items)
.block(Block::default().title("Comments").borders(Borders::ALL))
Expand All @@ -210,7 +221,13 @@ where
)
.highlight_symbol(tui::symbols::line::VERTICAL)
.repeat_highlight_symbol(true);
frame.render_stateful_widget(list, chunks[0], &mut app.comment_state);
let sort_text = Paragraph::new(" New[1] Old[2] Hot[3]").style(
Style::default()
.fg(*app.theme.get(PRIMARY).unwrap())
.bg(*app.theme.get(BG).unwrap()),
);
frame.render_widget(sort_text, chunks[0]);
frame.render_stateful_widget(list, chunks[1], &mut app.comment_state);
} else if let (_, false) = (&app.comments, app.replies.is_empty()) {
let chunks = Layout::default()
.direction(Direction::Vertical)
Expand All @@ -220,32 +237,29 @@ where
let mut items = vec![];

for comment in &app.replies {
//Comment can be null :(
if let Some(c) = comment.comment.comment.as_ref() {
let mut t = WrappedText::new(frame.size().width - 10);
t.extend(Text::from(vec![
Spans::from(vec![Span::styled(
&comment.comment.creator.name,
Style::default()
.fg(*app.theme.get(SECONDARY).unwrap())
.bg(*app.theme.get(BG).unwrap())
.add_modifier(Modifier::UNDERLINED),
)]),
Spans::from(c.content.as_ref()),
Spans::from(vec![
Span::styled(
format!("{}", comment.children.len()),
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
Span::styled(
" Replies",
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
]),
Spans::from(""),
]));
items.push(ListItem::new(t))
}
let mut t = WrappedText::new(frame.size().width - 10);
t.extend(Text::from(vec![
Spans::from(vec![Span::styled(
&comment.comment.creator.name,
Style::default()
.fg(*app.theme.get(SECONDARY).unwrap())
.bg(*app.theme.get(BG).unwrap())
.add_modifier(Modifier::UNDERLINED),
)]),
Spans::from(comment.comment.comment.content.as_ref()),
Spans::from(vec![
Span::styled(
format!("{}", comment.children.len()),
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
Span::styled(
" Replies",
Style::default().fg(*app.theme.get(SECONDARY).unwrap()),
),
]),
Spans::from(""),
]));
items.push(ListItem::new(t))
}

let list = List::new(items)
Expand Down
Loading

0 comments on commit e3e3066

Please sign in to comment.