Skip to content

Commit

Permalink
Merge pull request #375 from squidowl/feat/overwrite-nick-color
Browse files Browse the repository at this point in the history
feat: overwrite nick color
  • Loading branch information
casperstorm committed May 14, 2024
2 parents f50dd6c + aa6a6e4 commit e48ad4b
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 41 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

Added:

- Ability to overwrite nickname colors by providing a hex string (see [buffer configuration](https://halloy.squidowl.org/configuration/buffer.html#buffernicknamecolor-section)).

# 2024.7 (2024-05-05)

Added:
Expand Down
44 changes: 35 additions & 9 deletions book/src/configuration/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,31 @@

## `[buffer.nickname]` Section

### `[buffer.nickname.color]` Section

```toml
[buffer.nickname]
color = "unique" | "solid"
brackets = { left = "<string>", right = "<string>" }
[buffer.nickname.color]
kind = "unique" | "solid"
hex = "<string>"
```

| Key | Description | Default |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `kind` | Controls whether nickname color is `"solid"` or `"unique"`. `"unique"` generates colors by randomzing a hue which is used together with the saturation and lightness from the action color provided by the theme. This color can be overwritten with `hex`. | `kind = "unique"` |
| `hex` | Overwrite the default color. Optional. | `not set` |

### `[buffer.nickname.brackets]` Section

```toml
[buffer.nickname.brackets]
left = "<string>"
right = "<string>"
```

| Key | Description | Default |
| ---------- | ------------------------------------------------ | --------------------------- |
| `color` | Nickname colors. Can be `"unique"` or `"solid"`. | `"unique"` |
| `brackets` | Brackets for nicknames. | `{ left = "", right = "" }` |
| Key | Description | Default |
| ------- | ---------------------------- | ------------ |
| `left` | Left bracket for nicknames. | `left = ""` |
| `right` | Right bracket for nicknames. | `right = ""` |

## `[buffer.timestamp]` Section

Expand Down Expand Up @@ -47,14 +62,25 @@ visibility = "always" | "focused"
[buffer.channel.nicklist]
enabled = true | false
position = "left" | "right"
color = "unique" | "solid"
```

| Key | Description | Default |
| ---------- | ------------------------------------------------ | ---------- |
| `enabled` | Control if nicklist should be shown or not | `true` |
| `position` | Nicklist position. Can be `"left"` or `"right"`. | `"right"` |
| `color` | Nickname colors. Can be `"unique"` or `"solid"`. | `"unique"` |

### `[buffer.channel.nicklist.color]` Section

```toml
[buffer.channel.nicklist.color]
kind = "unique" | "solid"
hex = "<string>"
```

| Key | Description | Default |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `kind` | Controls whether nickname color is `"solid"` or `"unique"`. `"unique"` generates colors by randomzing a hue which is used together with the saturation and lightness from the action color provided by the theme. This color can be overwritten with `hex`. | `kind = "unique"` |
| `hex` | Overwrite the default color. Optional. | `not set` |

### `[buffer.channel.topic]` Section

Expand Down
37 changes: 35 additions & 2 deletions data/src/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt;

use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};

use crate::user::Nick;
use crate::{channel, config, message, Server};
Expand Down Expand Up @@ -111,12 +111,45 @@ impl Brackets {

#[derive(Debug, Clone, Copy, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Color {
pub enum ColorKind {
Solid,
#[default]
Unique,
}

#[derive(Debug, Clone, Default)]
pub struct Color {
pub kind: ColorKind,
pub hex: Option<String>,
}

// Support backwards compatibility of deserializing
// from a single "color kind" string
impl<'de> Deserialize<'de> for Color {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Data {
kind: ColorKind,
hex: Option<String>,
}

#[derive(Deserialize)]
#[serde(untagged)]
enum Format {
Kind(ColorKind),
Data(Data),
}

Ok(match Format::deserialize(deserializer)? {
Format::Kind(kind) => Color { kind, hex: None },
Format::Data(Data { kind, hex }) => Color { kind, hex },
})
}
}

#[derive(Debug, Clone, Copy)]
pub enum Resize {
None,
Expand Down
2 changes: 1 addition & 1 deletion data/src/config/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl Default for Buffer {
Buffer {
timestamp: Timestamp::default(),
nickname: Nickname {
color: Color::Unique,
color: Color::default(),
brackets: Default::default(),
},
text_input: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion data/src/config/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct Channel {
pub topic: Topic,
}

#[derive(Debug, Clone, Copy, Deserialize)]
#[derive(Debug, Clone, Deserialize)]
pub struct Nicklist {
#[serde(default = "default_bool_true")]
pub enabled: bool,
Expand Down
2 changes: 1 addition & 1 deletion data/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl Default for Palette {
}
}

fn hex_to_color(hex: &str) -> Option<Color> {
pub fn hex_to_color(hex: &str) -> Option<Color> {
if hex.len() == 7 {
let hash = &hex[0..1];
let r = u8::from_str_radix(&hex[1..3], 16);
Expand Down
33 changes: 28 additions & 5 deletions data/src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ use std::hash::Hash;
use irc::proto;
use serde::{Deserialize, Serialize};

use crate::{buffer, config::buffer::UsernameFormat, mode};
use crate::{
buffer,
config::buffer::UsernameFormat,
mode,
theme::{hex_to_color, Colors},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(into = "String")]
Expand Down Expand Up @@ -120,10 +125,22 @@ impl From<Nick> for User {
}

impl User {
pub fn color_seed(&self, color: &buffer::Color) -> Option<String> {
match color {
buffer::Color::Solid => None,
buffer::Color::Unique => Some(self.nickname().as_ref().to_string()),
pub fn nick_color(&self, colors: &Colors, color: &buffer::Color) -> NickColor {
let buffer::Color { kind, hex } = color;
let color = hex
.as_deref()
.and_then(hex_to_color)
.unwrap_or(colors.action.base);

match kind {
buffer::ColorKind::Solid => NickColor {
seed: None,
color,
},
buffer::ColorKind::Unique => NickColor {
seed: Some(self.nickname().as_ref().to_string()),
color,
},
}
}

Expand Down Expand Up @@ -211,6 +228,12 @@ impl fmt::Display for User {
}
}

#[derive(Debug, Clone)]
pub struct NickColor {
pub seed: Option<String>,
pub color: iced_core::Color,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Nick(String);

Expand Down
4 changes: 2 additions & 2 deletions src/buffer/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn view<'a>(
|theme| {
theme::selectable_text::nickname(
theme,
user.color_seed(&config.buffer.nickname.color),
user.nick_color(theme.colors(), &config.buffer.nickname.color),
user.is_away(),
)
},
Expand Down Expand Up @@ -304,7 +304,7 @@ mod nick_list {
let content = text(user.to_string()).style(|theme| {
theme::text::nickname(
theme,
user.color_seed(&config.buffer.channel.nicklist.color),
user.nick_color(theme.colors(), &config.buffer.channel.nicklist.color),
user.is_away(),
)
});
Expand Down
2 changes: 1 addition & 1 deletion src/buffer/channel/topic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn view<'a>(
selectable_text(who).style(|theme| {
theme::selectable_text::nickname(
theme,
user.color_seed(&config.buffer.nickname.color),
user.nick_color(theme.colors(), &config.buffer.nickname.color),
false,
)
}),
Expand Down
2 changes: 1 addition & 1 deletion src/buffer/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn view<'a>(
|theme| {
theme::selectable_text::nickname(
theme,
user.color_seed(&config.buffer.nickname.color),
user.nick_color(theme.colors(), &config.buffer.nickname.color),
false,
)
},
Expand Down
2 changes: 1 addition & 1 deletion src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl Theme {
}
}

fn colors(&self) -> &Colors {
pub fn colors(&self) -> &Colors {
match self {
Theme::Selected(selected) => &selected.colors,
Theme::Preview { preview, .. } => &preview.colors,
Expand Down
6 changes: 3 additions & 3 deletions src/theme/selectable_text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use data::message;
use data::{message, user::NickColor};

use crate::widget::selectable_text::{Catalog, Style, StyleFn};

Expand Down Expand Up @@ -46,8 +46,8 @@ pub fn accent(theme: &Theme) -> Style {
}
}

pub fn nickname(theme: &Theme, seed: Option<String>, transparent: bool) -> Style {
let color = text::nickname(theme, seed, transparent).color;
pub fn nickname(theme: &Theme, nick_color: NickColor, transparent: bool) -> Style {
let color = text::nickname(theme, nick_color, transparent).color;

Style {
color,
Expand Down
25 changes: 11 additions & 14 deletions src/theme/text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use data::theme::{alpha, randomize_color};
use data::{theme::{alpha, randomize_color}, user::NickColor};
use iced::widget::text::{Catalog, Style, StyleFn};

use super::Theme;
Expand Down Expand Up @@ -67,29 +67,26 @@ pub fn transparent_accent(theme: &Theme) -> Style {
}
}

pub fn nickname(theme: &Theme, seed: Option<String>, transparent: bool) -> Style {
pub fn nickname(theme: &Theme, nick_color: NickColor, transparent: bool) -> Style {
let dark_theme = theme.colors().is_dark_theme();
let NickColor { color, seed } = nick_color;

if seed.is_none() {
let color = match transparent {
true => theme.colors().text.med_alpha,
false => theme.colors().text.base,
let Some(seed) = seed else {
let color = if transparent {
alpha(color, if dark_theme { 0.2 } else { 0.4 })
} else {
color
};

return Style { color: Some(color) };
}

let original_color = theme.colors().action.base;
let randomized_color = seed
.as_deref()
.map(|seed| randomize_color(original_color, seed))
.unwrap_or_else(|| original_color);
};

let randomized_color = randomize_color(color, &seed);
let color = if transparent {
alpha(randomized_color, if dark_theme { 0.2 } else { 0.4 })
} else {
randomized_color
};

Style { color: Some(color) }
Style { color: Some(color) }
}

0 comments on commit e48ad4b

Please sign in to comment.