use std::sync::atomic::{AtomicU16, Ordering};
use tui::{
prelude::*,
style::Style,
widgets::{Block, Borders},
};
mod post;
mod posts_list;
pub use post::*;
pub use posts_list::*;
pub const PURPLE: Color = Color::Rgb(0x80, 0x00, 0x80);
pub const GRAY: Color = Color::Rgb(0xbf, 0xba, 0xbe);
pub const DARK_GRAY: Color = Color::Rgb(0x3f, 0x3a, 0x3e);
pub const WHITE_SMOKE: Color = Color::Rgb(0xf5, 0xf5, 0xf5);
static CURRENT_SCREEN: AtomicU16 = AtomicU16::new(0);
pub fn current_screen() -> Screen {
CURRENT_SCREEN.load(Ordering::Relaxed).into()
}
pub fn set_current_screen(screen: Screen) {
CURRENT_SCREEN.store(screen.into(), Ordering::SeqCst);
}
#[repr(u16)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub enum Screen {
#[default]
PostList = 0,
Post,
Image,
CommentList,
Comment,
}
impl From<u16> for Screen {
fn from(val: u16) -> Self {
match val {
0 => Self::PostList,
1 => Self::Post,
2 => Self::Image,
3 => Self::CommentList,
4 => Self::Comment,
_ => Self::PostList,
}
}
}
impl From<usize> for Screen {
fn from(val: usize) -> Screen {
(val as u16).into()
}
}
impl From<&Screen> for u16 {
fn from(val: &Screen) -> Self {
*val as u16
}
}
impl From<Screen> for u16 {
fn from(val: Screen) -> Self {
(&val).into()
}
}
pub fn title_block(title: &str) -> Block {
Block::default()
.borders(Borders::ALL)
.style(header_style())
.title(Span::styled(
title,
Style::default().add_modifier(Modifier::BOLD),
))
}
pub fn screen_style() -> Style {
Style::default().fg(PURPLE).bg(Color::Black)
}
pub fn header_style() -> Style {
Style::default().fg(WHITE_SMOKE).bg(Color::Black)
}
pub fn list_style() -> Style {
Style::default().fg(Color::Green).bg(Color::Black)
}
pub fn body_style() -> Style {
Style::default().fg(Color::Green).bg(Color::Black)
}
pub fn highlight_style() -> Style {
Style::default().fg(PURPLE).bg(GRAY)
}
pub fn split_cells(text: &str, width: usize, out: &mut [String]) -> usize {
let mut cell_idx = 0;
let num_cells = out.len();
let mut height = 1;
let stripped: String = text.chars().filter(|&c| c != '\r' && c != '\n').collect();
for c in stripped.as_bytes().chunks(width) {
if height != 1 {
out[cell_idx] += format!("\n{}", std::str::from_utf8(c).unwrap_or("")).as_str();
} else {
out[cell_idx] += std::str::from_utf8(c).unwrap_or("");
}
cell_idx = (cell_idx + 1) % num_cells;
if cell_idx == 0 {
height += 1;
}
}
height
}
pub fn wrapped_height(text_width: usize, screen_width: usize) -> usize {
if screen_width == 0 {
0
} else {
(text_width / screen_width).saturating_add(text_width % screen_width) + 1
}
}