Skip to content

Commit

Permalink
More tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
tarkah committed Sep 6, 2024
1 parent f9e0e24 commit 5e63ce2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 54 deletions.
76 changes: 44 additions & 32 deletions data/src/url.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use log::warn;
use regex::Regex;

use crate::{config, theme, Server};
Expand All @@ -15,6 +16,7 @@ pub enum Url {
url: String,
colors: theme::Colors,
},
Unknown(String),
}

impl std::fmt::Display for Url {
Expand All @@ -23,7 +25,7 @@ impl std::fmt::Display for Url {
f,
"{}",
match self {
Url::ServerConnect { url, .. } | Url::Theme { url, .. } => url,
Url::ServerConnect { url, .. } | Url::Theme { url, .. } | Url::Unknown(url) => url,
}
)
}
Expand All @@ -40,38 +42,48 @@ impl Url {
}

impl FromStr for Url {
type Err = Error;
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
let url = s.parse::<url::Url>()?;

match url.scheme().to_lowercase().as_str() {
"irc" | "ircs" => {
let config = parse_server_config(&url).ok_or(Error::ParseServer)?;
let server = generate_server_name(config.server.as_str());
let url = url.into();

Ok(Self::ServerConnect {
url,
server: server.into(),
config,
})
}
"halloy" if url.path() == "/theme" => {
let (_, encoded) = url
.query_pairs()
.find(|(key, _)| key == "e")
.ok_or(Error::MissingQueryPair)?;

let colors = theme::Colors::decode_base64(&encoded)?;

Ok(Self::Theme {
url: url.into(),
colors,
})
}
_ => Err(Error::Unsupported),
let url = s.parse::<url::Url>().map_err(|_| ())?;

if ["irc", "ircs", "halloy"].contains(&url.scheme()) {
Ok(parse(url.clone())
.inspect_err(|err| warn!("Failed to parse url {url}: {err}"))
.unwrap_or(Url::Unknown(url.to_string())))
} else {
Err(())
}
}
}

fn parse(url: url::Url) -> Result<Url, Error> {
match url.scheme().to_lowercase().as_str() {
"irc" | "ircs" => {
let config = parse_server_config(&url).ok_or(Error::ParseServer)?;
let server = generate_server_name(config.server.as_str());
let url = url.into();

Ok(Url::ServerConnect {
url,
server: server.into(),
config,
})
}
"halloy" if url.path() == "/theme" => {
let (_, encoded) = url
.query_pairs()
.find(|(key, _)| key == "e")
.ok_or(Error::MissingQueryPair)?;

let colors = theme::Colors::decode_base64(&encoded)?;

Ok(Url::Theme {
url: url.into(),
colors,
})
}
_ => Err(Error::Unknown),
}
}

Expand Down Expand Up @@ -143,8 +155,8 @@ pub enum Error {
ParseUrl(#[from] url::ParseError),
#[error("can't convert url to a valid server")]
ParseServer,
#[error("unsupported route")]
Unsupported,
#[error("unknown route")]
Unknown,
#[error("missing query pair")]
MissingQueryPair,
#[error("failed to parse encoded theme: {0}")]
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ impl Halloy {
.map(Message::Dashboard);
}
}
data::Url::Unknown(url) => {
log::warn!("Received unknown url: {url}");
}
}

Task::none()
Expand Down
53 changes: 32 additions & 21 deletions src/screen/dashboard/theme_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct ThemeEditor {
pub id: window::Id,
combo_box: combo_box::State<Component>,
component: Component,
hex_input: String,
hex_input: Option<String>,
save_result: Option<bool>,
copied: bool,
}
Expand All @@ -67,8 +67,10 @@ impl ThemeEditor {
Self {
id,
combo_box: combo_box::State::new(components().collect()),
component: Component::General(General::Background),
hex_input: String::default(),
// Defaulting to general / background is confusing
// since picker is same color as background
component: Component::Text(Text::Primary),
hex_input: None,
save_result: None,
copied: false,
},
Expand All @@ -85,7 +87,7 @@ impl ThemeEditor {
) -> (Task<Message>, Option<Event>) {
match message {
Message::Color(color) => {
self.hex_input.clear();
self.hex_input = None;

let mut colors = *theme.colors();

Expand All @@ -94,21 +96,21 @@ impl ThemeEditor {
*theme = theme.preview(data::Theme::new("Custom Theme".into(), colors));
}
Message::Component(component) => {
self.hex_input.clear();
self.hex_input = None;
self.combo_box = combo_box::State::new(components().collect());

self.component = component
}
Message::HexInput(input) => {
self.hex_input = input;

if let Some(color) = theme::hex_to_color(&self.hex_input) {
if let Some(color) = theme::hex_to_color(&input) {
let mut colors = *theme.colors();

self.component.update(&mut colors, Some(color));

*theme = theme.preview(data::Theme::new("Custom Theme".into(), colors));
}

self.hex_input = Some(input);
}
Message::Save => {
let task = async move {
Expand All @@ -134,7 +136,7 @@ impl ThemeEditor {
return (Task::none(), Some(Event::Close));
}
Message::Revert => {
self.hex_input.clear();
self.hex_input = None;

let mut colors = *theme.selected().colors();
let original = self.component.color(&colors);
Expand All @@ -144,7 +146,7 @@ impl ThemeEditor {
*theme = theme.preview(data::Theme::new("Custom Theme".into(), colors));
}
Message::Clear => {
self.hex_input.clear();
self.hex_input = None;

let mut colors = *theme.colors();

Expand Down Expand Up @@ -222,17 +224,26 @@ impl ThemeEditor {
Message::Component,
);

let is_input_valid =
self.hex_input.is_empty() || theme::hex_to_color(&self.hex_input).is_some();
let hex_input = text_input(&theme::color_to_hex(color), &self.hex_input)
.on_input(Message::HexInput)
.style(move |theme, status| {
if is_input_valid {
theme::text_input::primary(theme, status)
} else {
theme::text_input::error(theme, status)
}
});
let is_input_valid = self.hex_input.is_none()
|| self
.hex_input
.as_deref()
.and_then(theme::hex_to_color)
.is_some();
let hex_input = text_input(
"",
self.hex_input
.as_deref()
.unwrap_or(theme::color_to_hex(color).as_str()),
)
.on_input(Message::HexInput)
.style(move |theme, status| {
if is_input_valid {
theme::text_input::primary(theme, status)
} else {
theme::text_input::error(theme, status)
}
});

let undo = icon(icon::undo(), "Revert", Message::Revert);
let clear = icon(icon::delete(), "Clear", Message::Clear);
Expand Down
7 changes: 6 additions & 1 deletion src/widget/color_picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,12 @@ fn slider<'a, Message: 'a>(
let bounds = layout.bounds();
let handle = slider_handle(value, color, bounds, handle_radius);

let color = Hsva::new_srgb(color.hue, 1.0, 1.0, 1.0);
let color = match component {
// Full S/V and cycle every hue
Component::Hue => Hsva::new_srgb(0.0, 1.0, 1.0, 1.0),
// Otherwise slide should change based on color
_ => color,
};

for x in 0..bounds.width as usize {
renderer.fill_quad(
Expand Down

0 comments on commit 5e63ce2

Please sign in to comment.