Turn hardcoded strings into constants to resolve #4

This commit is contained in:
2024-07-10 20:04:11 -04:00
parent 0d50da7ceb
commit 4fbd53efa5
5 changed files with 146 additions and 132 deletions

11
src/constants.rs Normal file
View File

@@ -0,0 +1,11 @@
pub const APP_TITLE: &str = "AntiDrift";
pub const INTENTION_TITLE: &str = "Intention";
pub const DURATION_TITLE: &str = "Duration";
pub const PREVIOUS_SESSIONS_TITLE: &str = "Previous Sessions";
pub const SESSION_STATS_TITLE: &str = "Session Stats";
pub const STATUS_TITLE: &str = "Status";
pub const PROVIDE_INTENTION: &str = "Provide intention! ";
pub const PROVIDE_VALID_DURATION: &str = "Provide valid duration in minutes! ";
pub const READY_TO_START: &str = "Ready to start next session.";
pub const SESSION_IN_PROGRESS: &str = "Session In-Progress";
pub const RATE_TITLES: &str = "Press 1, 2, 3 to rate titles!";

View File

@@ -3,6 +3,7 @@ use std::collections::HashMap;
use std::io::stdout; use std::io::stdout;
use std::rc::Rc; use std::rc::Rc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
mod constants;
mod window; mod window;
use ratatui::{ use ratatui::{
@@ -144,7 +145,7 @@ impl App {
self.user_duration = Duration::ZERO; self.user_duration = Duration::ZERO;
} }
window::minimize_other("AntiDrift"); window::minimize_other(&constants::APP_TITLE);
} }
State::InProgress => { State::InProgress => {
let elapsed = self.session_start.elapsed(); let elapsed = self.session_start.elapsed();
@@ -157,7 +158,7 @@ impl App {
} }
State::ShouldQuit => {} State::ShouldQuit => {}
State::End => { State::End => {
window::minimize_other("AntiDrift"); window::minimize_other(&constants::APP_TITLE);
} }
} }
@@ -375,7 +376,7 @@ fn ui(frame: &mut Frame, app: &App) {
Paragraph::new(input_intention).block( Paragraph::new(input_intention).block(
Block::bordered() Block::bordered()
.border_type(border_type_intention) .border_type(border_type_intention)
.title("Intention"), .title(constants::INTENTION_TITLE),
), ),
layout_intention, layout_intention,
); );
@@ -395,7 +396,7 @@ fn ui(frame: &mut Frame, app: &App) {
Paragraph::new(input_duration).block( Paragraph::new(input_duration).block(
Block::bordered() Block::bordered()
.border_type(border_type_duration) .border_type(border_type_duration)
.title("Duration"), .title(constants::DURATION_TITLE),
), ),
layout_duration, layout_duration,
); );
@@ -403,26 +404,30 @@ fn ui(frame: &mut Frame, app: &App) {
if app.state == State::InputIntention || app.state == State::InputDuration { if app.state == State::InputIntention || app.state == State::InputDuration {
let results = app.get_session_results(); let results = app.get_session_results();
frame.render_widget( frame.render_widget(
Paragraph::new(results).block(Block::bordered().title("Previous Sessions")), Paragraph::new(results)
.block(Block::bordered().title(constants::PREVIOUS_SESSIONS_TITLE)),
layout_titles, layout_titles,
); );
} else { } else {
let stats = app.get_session_stats(); let stats = app.get_session_stats();
frame.render_widget( frame.render_widget(
Paragraph::new(stats).block(Block::bordered().title("Session Stats")), Paragraph::new(stats).block(Block::bordered().title(constants::SESSION_STATS_TITLE)),
layout_titles, layout_titles,
); );
} }
let mut spans: Vec<Span> = Vec::new(); let mut spans: Vec<Span> = Vec::new();
if app.user_intention.len() == 0 { if app.user_intention.len() == 0 {
let span = Span::styled("Provide intention! ", Style::new().fg(Color::LightRed)); let span = Span::styled(
constants::PROVIDE_INTENTION,
Style::new().fg(Color::LightRed),
);
spans.push(span); spans.push(span);
} }
if app.user_duration == Duration::ZERO { if app.user_duration == Duration::ZERO {
let span = Span::styled( let span = Span::styled(
"Provide valid duration in minutes! ", constants::PROVIDE_VALID_DURATION,
Style::new().fg(Color::LightRed), Style::new().fg(Color::LightRed),
); );
spans.push(span); spans.push(span);
@@ -432,29 +437,29 @@ fn ui(frame: &mut Frame, app: &App) {
State::InputIntention | State::InputDuration => { State::InputIntention | State::InputDuration => {
if spans.len() == 0 { if spans.len() == 0 {
let span = Span::styled( let span = Span::styled(
"Ready to start next session.", constants::READY_TO_START,
Style::new().fg(Color::LightGreen), Style::new().fg(Color::LightGreen),
); );
spans.push(span); spans.push(span);
} }
} }
State::InProgress => { State::InProgress => {
let span = Span::styled("Session In-Progress", Style::new().fg(Color::LightGreen)); let span = Span::styled(
constants::SESSION_IN_PROGRESS,
Style::new().fg(Color::LightGreen),
);
spans.push(span); spans.push(span);
} }
State::ShouldQuit => {} State::ShouldQuit => {}
State::End => { State::End => {
let span = Span::styled( let span = Span::styled(constants::RATE_TITLES, Style::new().fg(Color::LightBlue));
"Press 1, 2, 3 to rate titles!",
Style::new().fg(Color::LightBlue),
);
spans.push(span); spans.push(span);
} }
} }
let input_status: Vec<Line> = vec![Line::from(spans)]; let input_status: Vec<Line> = vec![Line::from(spans)];
frame.render_widget( frame.render_widget(
Paragraph::new(input_status).block(Block::bordered().title("Status")), Paragraph::new(input_status).block(Block::bordered().title(constants::STATUS_TITLE)),
layout_status, layout_status,
); );
} }

View File

@@ -1,70 +1,70 @@
use regex::Regex; use regex::Regex;
use std::{process::Command, process::Output, str}; use std::{process::Command, process::Output, str};
pub fn get_title_clean() -> String { pub fn get_title_clean() -> String {
let title = get_window_info().title; let title = get_window_info().title;
let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap(); let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap();
re.replace_all(&title, "").to_string() re.replace_all(&title, "").to_string()
} }
pub fn minimize_other(title: &str) { pub fn minimize_other(title: &str) {
let window_info = get_window_info(); let window_info = get_window_info();
if &window_info.title != title { if &window_info.title != title {
run(&format!("xdotool windowminimize {}", window_info.wid)); run(&format!("xdotool windowminimize {}", window_info.wid));
} }
} }
struct WindowInfo { struct WindowInfo {
title: String, title: String,
_class: String, _class: String,
wid: String, wid: String,
} }
fn run(cmd: &str) -> Option<String> { fn run(cmd: &str) -> Option<String> {
let output = Command::new("sh").arg("-c").arg(cmd).output(); let output = Command::new("sh").arg("-c").arg(cmd).output();
let Ok(Output { let Ok(Output {
status, status,
stdout, stdout,
stderr: _, stderr: _,
}) = output }) = output
else { else {
return None; return None;
}; };
if status.code() != Some(0) { if status.code() != Some(0) {
return None; return None;
} }
let Ok(output_str) = str::from_utf8(&stdout) else { let Ok(output_str) = str::from_utf8(&stdout) else {
return None; return None;
}; };
Some(output_str.trim().to_string()) Some(output_str.trim().to_string())
} }
fn get_window_info() -> WindowInfo { fn get_window_info() -> WindowInfo {
let none = WindowInfo { let none = WindowInfo {
title: "none".to_string(), title: "none".to_string(),
_class: "none".to_string(), _class: "none".to_string(),
wid: "".to_string(), wid: "".to_string(),
}; };
let Some(wid) = run("xdotool getactivewindow") else { let Some(wid) = run("xdotool getactivewindow") else {
return none; return none;
}; };
let Some(class) = run(&format!("xdotool getwindowclassname {wid}")) else { let Some(class) = run(&format!("xdotool getwindowclassname {wid}")) else {
return none; return none;
}; };
let Some(title) = run(&format!("xdotool getwindowname {wid}")) else { let Some(title) = run(&format!("xdotool getwindowname {wid}")) else {
return none; return none;
}; };
WindowInfo { WindowInfo {
title, title,
_class: class, _class: class,
wid, wid,
} }
} }

View File

@@ -1,9 +1,9 @@
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod windows; mod windows;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub use windows::*; pub use windows::*;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod linux; mod linux;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub use linux::*; pub use linux::*;

View File

@@ -1,38 +1,36 @@
use regex::Regex; use regex::Regex;
use std::{ffi::OsString, os::windows::ffi::OsStringExt}; use std::{ffi::OsString, os::windows::ffi::OsStringExt};
use winapi::shared::windef::HWND; use winapi::shared::windef::HWND;
use winapi::um::winuser::{ShowWindow, SW_MINIMIZE, GetForegroundWindow, GetWindowTextW}; use winapi::um::winuser::{GetForegroundWindow, GetWindowTextW, ShowWindow, SW_MINIMIZE};
pub fn get_title_clean() -> String {
pub fn get_title_clean() -> String { let title = get_window_info().title;
let title = get_window_info().title; let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap();
let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap(); re.replace_all(&title, "").to_string()
re.replace_all(&title, "").to_string() }
}
pub fn minimize_other(title: &str) {
pub fn minimize_other(title: &str) { let window_info = get_window_info();
let window_info = get_window_info(); if window_info.title != title {
if window_info.title != title { unsafe {
unsafe { ShowWindow(window_info.hwnd, SW_MINIMIZE);
ShowWindow(window_info.hwnd, SW_MINIMIZE); }
} }
} }
}
struct WindowInfo {
struct WindowInfo { title: String,
title: String, hwnd: HWND,
hwnd: HWND, }
}
fn get_window_info() -> WindowInfo {
fn get_window_info() -> WindowInfo { unsafe {
unsafe { let hwnd = GetForegroundWindow();
let hwnd = GetForegroundWindow(); let mut text: [u16; 512] = [0; 512];
let mut text: [u16; 512] = [0; 512]; let len = GetWindowTextW(hwnd, text.as_mut_ptr(), text.len() as i32) as usize;
let len = GetWindowTextW(hwnd, text.as_mut_ptr(), text.len() as i32) as usize; let title = OsString::from_wide(&text[..len])
let title = OsString::from_wide(&text[..len]).to_string_lossy().into_owned(); .to_string_lossy()
WindowInfo { .into_owned();
title, WindowInfo { title, hwnd }
hwnd, }
} }
}
}