Skip to content

Commit

Permalink
added support for RTL texts (hebrew & arabic)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ofir Gal committed Jan 10, 2022
1 parent c4dcf6b commit 8d2d5cd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 33 deletions.
8 changes: 3 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ crossterm = "0.20"
tokio = { version = "0.2", features = ["full"] }
rand = "0.8.4"
anyhow = "1.0.43"
unicode-bidi = "0.3.7"

[[bin]]
bench = false
Expand Down
56 changes: 28 additions & 28 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use tui::{
Frame,
};
use util::{
create_artist_string, display_track_progress, get_artist_highlight_state, get_color,
create_artist_string, fix_rtl_string, display_track_progress, get_artist_highlight_state, get_color,
get_percentage_width, get_search_results_highlight_state, get_track_progress_percentage,
millis_to_minutes, BASIC_VIEW_HEIGHT, SMALL_TERMINAL_WIDTH,
};
Expand Down Expand Up @@ -145,7 +145,7 @@ where
);

let input_string: String = app.input.iter().collect();
let lines = Text::from((&input_string).as_str());
let lines = Text::from(fix_rtl_string((&input_string).as_str()));
let input = Paragraph::new(lines).block(
Block::default()
.borders(Borders::ALL)
Expand Down Expand Up @@ -305,7 +305,7 @@ where
B: Backend,
{
let playlist_items = match &app.playlists {
Some(p) => p.items.iter().map(|item| item.name.to_owned()).collect(),
Some(p) => p.items.iter().map(|item| fix_rtl_string(&item.name.to_owned())).collect(),
None => vec![],
};

Expand Down Expand Up @@ -410,7 +410,7 @@ where

song_name += &item.name;
song_name += &format!(" - {}", &create_artist_string(&item.artists));
song_name
fix_rtl_string(&song_name)
})
.collect(),
None => vec![],
Expand All @@ -435,7 +435,7 @@ where
if app.followed_artist_ids_set.contains(&item.id.to_owned()) {
artist.push_str(&app.user_config.padded_liked_icon());
}
artist.push_str(&item.name.to_owned());
artist.push_str(&fix_rtl_string(&item.name.to_owned()));
artist
})
.collect(),
Expand Down Expand Up @@ -472,7 +472,7 @@ where
}
album_artist.push_str(&format!(
"{} - {} ({})",
item.name.to_owned(),
fix_rtl_string(&item.name.to_owned()),
create_artist_string(&item.artists),
item.album_type.as_deref().unwrap_or("unknown")
));
Expand All @@ -496,7 +496,7 @@ where
Some(playlists) => playlists
.items
.iter()
.map(|item| item.name.to_owned())
.map(|item| fix_rtl_string(&item.name.to_owned()))
.collect(),
None => vec![],
};
Expand Down Expand Up @@ -527,7 +527,7 @@ where
show_name.push_str(&app.user_config.padded_liked_icon());
}
show_name.push_str(&format!("{:} - {}", item.name, item.publisher));
show_name
fix_rtl_string(&show_name)
})
.collect(),
None => vec![],
Expand Down Expand Up @@ -702,11 +702,11 @@ where
],
})
.collect::<Vec<TableItem>>(),
title: format!(
title: fix_rtl_string(&format!(
"{} by {}",
selected_album_simplified.album.name,
create_artist_string(&selected_album_simplified.album.artists)
),
)),
selected_index: selected_album_simplified.selected_index,
})
}
Expand All @@ -728,11 +728,11 @@ where
],
})
.collect::<Vec<TableItem>>(),
title: format!(
title: fix_rtl_string(&format!(
"{} by {}",
selected_album.album.name,
create_artist_string(&selected_album.album.artists)
),
)),
selected_index: app.saved_album_tracks_index,
}),
None => None,
Expand Down Expand Up @@ -812,11 +812,11 @@ where
let recommendations_ui = match &app.recommendations_context {
Some(RecommendationsContext::Song) => format!(
"Recommendations based on Song \'{}\'",
&app.recommendations_seed
&fix_rtl_string(&app.recommendations_seed)
),
Some(RecommendationsContext::Artist) => format!(
"Recommendations based on Artist \'{}\'",
&app.recommendations_seed
&fix_rtl_string(&app.recommendations_seed)
),
None => "Recommendations".to_string(),
};
Expand Down Expand Up @@ -989,12 +989,12 @@ where
let (item_id, name, duration_ms) = match track_item {
PlayingItem::Track(track) => (
track.id.to_owned().unwrap_or_else(|| "".to_string()),
track.name.to_owned(),
fix_rtl_string(&track.name.to_owned()),
track.duration_ms,
),
PlayingItem::Episode(episode) => (
episode.id.to_owned(),
episode.name.to_owned(),
fix_rtl_string(&episode.name.to_owned()),
episode.duration_ms,
),
};
Expand All @@ -1006,8 +1006,8 @@ where
};

let play_bar_text = match track_item {
PlayingItem::Track(track) => create_artist_string(&track.artists),
PlayingItem::Episode(episode) => format!("{} - {}", episode.name, episode.show.name),
PlayingItem::Track(track) => fix_rtl_string(&create_artist_string(&track.artists)),
PlayingItem::Episode(episode) => fix_rtl_string(&format!("{} - {}", episode.name, episode.show.name)),
};

let lines = Text::from(Span::styled(
Expand Down Expand Up @@ -1213,15 +1213,15 @@ where
}
};
name.push_str(&top_track.name);
name
fix_rtl_string(&name)
})
.collect::<Vec<String>>();

draw_selectable_list(
f,
app,
chunks[0],
&format!("{} - Top Tracks", &artist.artist_name),
&fix_rtl_string(&format!("{} - Top Tracks", &artist.artist_name)),
&top_tracks,
get_artist_highlight_state(app, ArtistBlock::TopTracks),
Some(artist.selected_top_track_index),
Expand All @@ -1244,7 +1244,7 @@ where
create_artist_string(&item.artists),
item.album_type.as_deref().unwrap_or("unknown")
));
album_artist
fix_rtl_string(&album_artist)
})
.collect::<Vec<String>>();

Expand All @@ -1267,7 +1267,7 @@ where
artist.push_str(&app.user_config.padded_liked_icon());
}
artist.push_str(&item.name.to_owned());
artist
fix_rtl_string(&artist)
})
.collect::<Vec<String>>();

Expand Down Expand Up @@ -1323,7 +1323,7 @@ where
items
.devices
.iter()
.map(|device| ListItem::new(Span::raw(&device.name)))
.map(|device| ListItem::new(Span::raw(fix_rtl_string(&device.name))))
.collect()
}
}
Expand Down Expand Up @@ -1494,21 +1494,21 @@ where
let title = match &app.episode_table_context {
EpisodeTableContext::Simplified => match &app.selected_show_simplified {
Some(selected_show) => {
format!(
fix_rtl_string(&format!(
"{} by {}",
selected_show.show.name.to_owned(),
selected_show.show.publisher
)
))
}
None => "Episodes".to_owned(),
},
EpisodeTableContext::Full => match &app.selected_show_full {
Some(selected_show) => {
format!(
fix_rtl_string(&format!(
"{} by {}",
selected_show.show.name.to_owned(),
selected_show.show.publisher
)
))
}
None => "Episodes".to_owned(),
},
Expand Down Expand Up @@ -1784,7 +1784,7 @@ fn draw_table<B>(
.unwrap_or(0);

let rows = items.iter().skip(offset).enumerate().map(|(i, item)| {
let mut formatted_row = item.format.clone();
let mut formatted_row: Vec<String> = item.format.clone().into_iter().map(|x| fix_rtl_string(&x)).collect();
let mut style = Style::default().fg(app.user_config.theme.text); // default styling

// if table displays songs
Expand Down
13 changes: 13 additions & 0 deletions src/ui/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::super::app::{ActiveBlock, App, ArtistBlock, SearchResultBlock};
use crate::user_config::Theme;
use rspotify::model::artist::SimplifiedArtist;
use tui::style::Style;
use unicode_bidi::BidiInfo;

pub const BASIC_VIEW_HEIGHT: u16 = 6;
pub const SMALL_TERMINAL_WIDTH: u16 = 150;
Expand Down Expand Up @@ -39,6 +40,18 @@ pub fn get_color((is_active, is_hovered): (bool, bool), theme: Theme) -> Style {
}
}

pub fn fix_rtl_string(text: &str) -> String {
let bidi_info = BidiInfo::new(&text, None);
bidi_info.paragraphs
.iter()
.map(|para| {
bidi_info
.reorder_line(&para, para.range.clone())
.to_string()
})
.collect::<String>()
}

pub fn create_artist_string(artists: &[SimplifiedArtist]) -> String {
artists
.iter()
Expand Down

0 comments on commit 8d2d5cd

Please sign in to comment.