mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 19:45:23 +00:00
some work on the configuration file
This commit is contained in:
parent
6d48c87526
commit
4302b6189a
@ -1,3 +1,18 @@
|
||||
# Television configuration file
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# Ui settings
|
||||
# ----------------------------------------------------------------------------
|
||||
[ui]
|
||||
# Whether to use nerd font icons in the UI
|
||||
use_nerd_font_icons = false
|
||||
# How much space to allocate for the UI (in percentage of the screen)
|
||||
ui_scale = 80
|
||||
|
||||
# Keybindings
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# Channel mode keybindings
|
||||
[keybindings.Channel]
|
||||
esc = "Quit"
|
||||
down = "SelectNextEntry"
|
||||
@ -11,6 +26,7 @@ ctrl-y = "CopyEntryToClipboard"
|
||||
ctrl-r = "ToggleRemoteControl"
|
||||
ctrl-s = "ToggleSendToChannel"
|
||||
|
||||
# Remote control mode keybindings
|
||||
[keybindings.RemoteControl]
|
||||
esc = "Quit"
|
||||
down = "SelectNextEntry"
|
||||
@ -20,6 +36,7 @@ ctrl-p = "SelectPrevEntry"
|
||||
enter = "SelectEntry"
|
||||
ctrl-r = "ToggleRemoteControl"
|
||||
|
||||
# Send to channel mode keybindings
|
||||
[keybindings.SendToChannel]
|
||||
esc = "Quit"
|
||||
down = "SelectNextEntry"
|
||||
|
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@ -49,27 +49,12 @@ jobs:
|
||||
run: cargo clippy --all-targets --all-features --workspace -- -D warnings
|
||||
|
||||
docs:
|
||||
name: Docs
|
||||
name: Documentation
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTDOCFLAGS: -Dwarnings
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
- name: Configure cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Setup pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Clean docs folder
|
||||
run: cargo clean --doc
|
||||
- name: Build docs
|
||||
run: cargo doc --no-deps
|
||||
- name: Add redirect
|
||||
run: echo '<meta http-equiv="refresh" content="0;url=tv/index.html">' > target/doc/index.html
|
||||
- name: Remove lock file
|
||||
run: rm target/doc/.lock
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: target/doc
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- uses: dtolnay/install@cargo-docs-rs
|
||||
- run: cargo docs-rs
|
||||
|
4
TODO.md
4
TODO.md
@ -6,8 +6,8 @@
|
||||
# tasks
|
||||
|
||||
- [x] preview navigation
|
||||
- [x] add a way to open the selected file in the default editor (or maybe that
|
||||
should be achieved using pipes?) --> use xargs for that
|
||||
- [ ] add a way to open the selected file in the default editor (or maybe that
|
||||
should be achieved using pipes?) --> xargs
|
||||
- [x] maybe filter out image types etc. for now
|
||||
- [x] return selected entry on exit
|
||||
- [x] piping output to another command
|
||||
|
@ -7,7 +7,7 @@ use directories::ProjectDirs;
|
||||
use lazy_static::lazy_static;
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use serde::{de::Deserializer, Deserialize};
|
||||
use tracing::{error, info};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
use crate::{
|
||||
action::Action,
|
||||
@ -26,6 +26,23 @@ pub struct AppConfig {
|
||||
pub config_dir: PathBuf,
|
||||
}
|
||||
|
||||
const DEFAULT_UI_SCALE: u16 = 90;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct UiConfig {
|
||||
pub use_nerd_font_icons: bool,
|
||||
pub ui_scale: u16,
|
||||
}
|
||||
|
||||
impl Default for UiConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
use_nerd_font_icons: false,
|
||||
ui_scale: DEFAULT_UI_SCALE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Debug, Default, Deserialize)]
|
||||
pub struct Config {
|
||||
@ -36,6 +53,7 @@ pub struct Config {
|
||||
pub keybindings: KeyBindings,
|
||||
#[serde(default)]
|
||||
pub styles: Styles,
|
||||
pub ui: UiConfig,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
@ -51,34 +69,32 @@ lazy_static! {
|
||||
.map(PathBuf::from);
|
||||
}
|
||||
|
||||
const CONFIG_FILE_NAME: &str = "config.toml";
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Result<Self, config::ConfigError> {
|
||||
let default_config: Config = toml::from_str(CONFIG).unwrap();
|
||||
let default_config: Config =
|
||||
toml::from_str(CONFIG).expect("default config");
|
||||
|
||||
let data_dir = get_data_dir();
|
||||
let config_dir = get_config_dir();
|
||||
let mut builder = config::Config::builder()
|
||||
.set_default("data_dir", data_dir.to_str().unwrap())?
|
||||
.set_default("config_dir", config_dir.to_str().unwrap())?;
|
||||
|
||||
let config_files = [
|
||||
("config.json5", config::FileFormat::Json5),
|
||||
("config.json", config::FileFormat::Json),
|
||||
("config.yaml", config::FileFormat::Yaml),
|
||||
("config.toml", config::FileFormat::Toml),
|
||||
("config.ini", config::FileFormat::Ini),
|
||||
];
|
||||
let mut found_config = false;
|
||||
for (file, format) in &config_files {
|
||||
let source = config::File::from(config_dir.join(file))
|
||||
.format(*format)
|
||||
.required(false);
|
||||
builder = builder.add_source(source);
|
||||
if config_dir.join(file).exists() {
|
||||
found_config = true;
|
||||
}
|
||||
}
|
||||
if !found_config {
|
||||
error!("No configuration file found. Application may not behave as expected");
|
||||
// Load the default_config values as base defaults
|
||||
builder = builder.add_source(config::File::from_str(
|
||||
CONFIG,
|
||||
config::FileFormat::Toml,
|
||||
));
|
||||
|
||||
let source = config::File::from(config_dir.join(CONFIG_FILE_NAME))
|
||||
.format(config::FileFormat::Toml)
|
||||
.required(false);
|
||||
builder = builder.add_source(source);
|
||||
|
||||
if !config_dir.join(CONFIG_FILE_NAME).is_file() {
|
||||
warn!("No config file found at {:?}", config_dir);
|
||||
}
|
||||
|
||||
let mut cfg: Self = builder.build()?.try_deserialize()?;
|
||||
|
@ -370,7 +370,7 @@ impl Television {
|
||||
/// * `Result<()>` - An Ok result or an error.
|
||||
pub fn draw(&mut self, f: &mut Frame, area: Rect) -> Result<()> {
|
||||
let layout = Layout::build(
|
||||
&Dimensions::default(),
|
||||
&Dimensions::from(self.config.ui.ui_scale),
|
||||
area,
|
||||
!matches!(self.mode, Mode::Channel),
|
||||
);
|
||||
|
@ -12,6 +12,12 @@ impl Dimensions {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for Dimensions {
|
||||
fn from(x: u16) -> Self {
|
||||
Self::new(x, x)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Dimensions {
|
||||
fn default() -> Self {
|
||||
Self::new(UI_WIDTH_PERCENT, UI_HEIGHT_PERCENT)
|
||||
|
@ -31,12 +31,12 @@ impl Television {
|
||||
preview: &Arc<Preview>,
|
||||
) -> Result<()> {
|
||||
let mut preview_title_spans = Vec::new();
|
||||
if let Some(icon) = &selected_entry.icon {
|
||||
if selected_entry.icon.is_some() && self.config.ui.use_nerd_font_icons
|
||||
{
|
||||
let icon = selected_entry.icon.as_ref().unwrap();
|
||||
preview_title_spans.push(Span::styled(
|
||||
{
|
||||
// FIXME: this should be done using padding on the parent block
|
||||
let mut icon_str = String::from(" ");
|
||||
icon_str.push(icon.icon);
|
||||
let mut icon_str = String::from(icon.icon);
|
||||
icon_str.push(' ');
|
||||
icon_str
|
||||
},
|
||||
@ -53,6 +53,7 @@ impl Television {
|
||||
let preview_title = Paragraph::new(Line::from(preview_title_spans))
|
||||
.block(
|
||||
Block::default()
|
||||
.padding(Padding::horizontal(1))
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.border_style(Style::default().fg(BORDER_COLOR)),
|
||||
|
@ -64,6 +64,7 @@ impl Television {
|
||||
ResultsListColors::default()
|
||||
.result_name_fg(mode_color(self.mode)),
|
||||
),
|
||||
self.config.ui.use_nerd_font_icons,
|
||||
);
|
||||
|
||||
f.render_stateful_widget(
|
||||
|
@ -65,6 +65,7 @@ pub fn build_results_list<'a, 'b>(
|
||||
entries: &'a [Entry],
|
||||
list_direction: ListDirection,
|
||||
results_list_colors: Option<ResultsListColors>,
|
||||
use_icons: bool,
|
||||
) -> List<'a>
|
||||
where
|
||||
'b: 'a,
|
||||
@ -73,7 +74,8 @@ where
|
||||
List::new(entries.iter().map(|entry| {
|
||||
let mut spans = Vec::new();
|
||||
// optional icon
|
||||
if let Some(icon) = &entry.icon {
|
||||
if entry.icon.is_some() && use_icons {
|
||||
let icon = entry.icon.as_ref().unwrap();
|
||||
spans.push(Span::styled(
|
||||
icon.to_string(),
|
||||
Style::default().fg(Color::from_str(icon.color).unwrap()),
|
||||
@ -200,6 +202,7 @@ impl Television {
|
||||
&entries,
|
||||
ListDirection::BottomToTop,
|
||||
None,
|
||||
self.config.ui.use_nerd_font_icons,
|
||||
);
|
||||
|
||||
f.render_stateful_widget(
|
||||
|
Loading…
x
Reference in New Issue
Block a user