fix(power): alignment of remaining battery
This commit is contained in:
parent
090efbfad7
commit
97bcbc64ec
6 changed files with 121 additions and 35 deletions
|
|
@ -19,6 +19,10 @@ pub static LANGUAGE_LOADER: Lazy<FluentLanguageLoader> = Lazy::new(|| {
|
|||
.load_fallback_language(&Localizations)
|
||||
.expect("Error while loading fallback language");
|
||||
|
||||
// In test, disable the isolating markers to help with string assertion
|
||||
#[cfg(test)]
|
||||
loader.set_use_isolating(false);
|
||||
|
||||
loader
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ impl Default for PageInner {
|
|||
Self {
|
||||
config_helper: Option::default(),
|
||||
panel_config: Option::default(),
|
||||
outputs: vec![fl!("all")],
|
||||
outputs: vec![fl!("all-displays")],
|
||||
anchors: vec![
|
||||
Anchor(PanelAnchor::Left).to_string(),
|
||||
Anchor(PanelAnchor::Right).to_string(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use chrono::Duration;
|
||||
use chrono::{Duration, TimeDelta};
|
||||
use futures::FutureExt;
|
||||
use zbus::Connection;
|
||||
|
||||
|
|
@ -236,7 +236,6 @@ pub struct Battery {
|
|||
pub percent: f64,
|
||||
pub on_battery: bool,
|
||||
pub remaining_duration: Duration,
|
||||
pub remaining_time: String,
|
||||
}
|
||||
|
||||
async fn get_device_proxy<'a>() -> Result<upower_dbus::DeviceProxy<'a>, zbus::Error> {
|
||||
|
|
@ -321,30 +320,79 @@ impl Battery {
|
|||
let icon_name =
|
||||
format!("cosmic-applet-battery-level-{battery_percent}-{charging}symbolic",);
|
||||
|
||||
let remaining_time = |duration: Duration| {
|
||||
let total_seconds = duration.num_seconds();
|
||||
|
||||
let hours = total_seconds / 3600;
|
||||
let minutes = (total_seconds % 3600) / 60;
|
||||
let seconds = total_seconds % 60;
|
||||
|
||||
fl!(
|
||||
"battery",
|
||||
"remaining-time",
|
||||
time = format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
|
||||
)
|
||||
};
|
||||
|
||||
return Battery {
|
||||
icon_name,
|
||||
is_present,
|
||||
percent,
|
||||
on_battery,
|
||||
remaining_duration,
|
||||
remaining_time: remaining_time(remaining_duration),
|
||||
};
|
||||
}
|
||||
|
||||
Battery::default()
|
||||
}
|
||||
pub fn remaining_time(&self) -> String {
|
||||
if self.remaining_duration <= TimeDelta::zero() {
|
||||
return String::new()
|
||||
}
|
||||
|
||||
let total_seconds = self.remaining_duration.num_seconds();
|
||||
|
||||
let days = total_seconds / 86400;
|
||||
let hours = total_seconds % 86400 / 3600;
|
||||
let minutes = (total_seconds % 3600) / 60;
|
||||
|
||||
let mut time: Vec<String> = Vec::new();
|
||||
if days > 0 {
|
||||
time.push(fl!("battery", "day", value = days));
|
||||
}
|
||||
if hours > 0 {
|
||||
time.push(fl!("battery", "hour", value = hours));
|
||||
}
|
||||
if minutes > 0 {
|
||||
time.push(fl!("battery", "minute", value = minutes));
|
||||
}
|
||||
|
||||
if time.len() == 3 {
|
||||
let last = time.pop().unwrap();
|
||||
time = vec![time.join(", "), last];
|
||||
}
|
||||
let time = if time.is_empty() { fl!("battery", "less-than-minute")
|
||||
} else {time.join(&format!(" {} ", fl!("battery", "and"))) };
|
||||
|
||||
fl!(
|
||||
"battery",
|
||||
"remaining-time",
|
||||
time = time,
|
||||
action = if self.on_battery { "empty" } else { "full" }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_can_format_battery_remaining() {
|
||||
let cases = [
|
||||
(59, "Less than a minute until empty"),
|
||||
(300, "5 minutes until empty"),
|
||||
(305, "5 minutes until empty"),
|
||||
(330, "5 minutes until empty"),
|
||||
(360, "6 minutes until empty"),
|
||||
(3660, "1 hour and 1 minute until empty"),
|
||||
(10800, "3 hours until empty"),
|
||||
(969400, "11 days, 5 hours and 16 minutes until empty"),
|
||||
];
|
||||
for case in cases {
|
||||
let (actual, expected) = case;
|
||||
let battery = Battery {
|
||||
remaining_duration: Duration::new(actual, 0).unwrap(),
|
||||
on_battery: true,
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(battery.remaining_time(), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ mod backend;
|
|||
use self::backend::{GetCurrentPowerProfile, SetPowerProfile};
|
||||
use backend::{Battery, PowerProfile};
|
||||
|
||||
use chrono::TimeDelta;
|
||||
use cosmic::iced::Length;
|
||||
use cosmic::iced::{Alignment, Length};
|
||||
use cosmic::iced_widget::row;
|
||||
use cosmic::widget::{self, column, radio, settings, text};
|
||||
use cosmic::Apply;
|
||||
|
|
@ -79,18 +78,19 @@ fn battery_info() -> Section<crate::pages::Message> {
|
|||
.show_while::<Page>(|page| page.battery.is_present)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let battery_icon = widget::icon::from_name(page.battery.icon_name.clone());
|
||||
let battery_percent = text::body(format!("{}%", page.battery.percent));
|
||||
|
||||
let battery_time = text::body(if page.battery.remaining_duration > TimeDelta::zero() {
|
||||
&page.battery.remaining_time
|
||||
} else {
|
||||
""
|
||||
});
|
||||
let battery_label = text::body(format!(
|
||||
"{}% {}",
|
||||
page.battery.percent,
|
||||
page.battery.remaining_time()
|
||||
));
|
||||
|
||||
column::with_capacity(2)
|
||||
.spacing(8)
|
||||
.push(text::heading(§ion.title))
|
||||
.push(row!(battery_icon, battery_percent, battery_time).spacing(8))
|
||||
.push(
|
||||
row!(battery_icon, battery_label)
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(cosmic::theme::active().cosmic().space_xxxs()),
|
||||
)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,8 +156,8 @@ panel-style = Style
|
|||
.background-opacity = Background opacity
|
||||
|
||||
panel-applets = Configuration
|
||||
.dock-desc = Configure dock applets.
|
||||
.desc = Configure panel applets.
|
||||
.dock-desc = Configure dock applets
|
||||
.desc = Configure panel applets
|
||||
|
||||
panel-missing = Panel Configuration is Missing
|
||||
.desc = The panel configuration file is missing due to use of a custom configuration or it is corrupted.
|
||||
|
|
@ -304,7 +304,24 @@ power = Power & Battery
|
|||
.desc = Manage power settings
|
||||
|
||||
battery = Battery
|
||||
.remaining-time = ({ $time } left)
|
||||
.minute = { $value } { $value ->
|
||||
[one] minute
|
||||
*[other] minutes
|
||||
}
|
||||
.hour = { $value } { $value ->
|
||||
[one] hour
|
||||
*[other] hours
|
||||
}
|
||||
.day = { $value } { $value ->
|
||||
[one] day
|
||||
*[other] days
|
||||
}
|
||||
.less-than-minute = Less than a minute
|
||||
.and = and
|
||||
.remaining-time = ({ $time } until { $action ->
|
||||
[full] full
|
||||
*[other] empty
|
||||
})
|
||||
|
||||
power-mode = Power Mode
|
||||
.battery = Extended battery life
|
||||
|
|
|
|||
|
|
@ -156,8 +156,8 @@ panel-style = Style
|
|||
.background-opacity = Opacité de l'arrière-plan
|
||||
|
||||
panel-applets = Configuration
|
||||
.dock-desc = Configuration des applets du dock.
|
||||
.desc = Configuration des applets du panneau.
|
||||
.dock-desc = Configuration des applets du dock
|
||||
.desc = Configuration des applets du panneau
|
||||
|
||||
panel-missing = La configuration du panneau est manquante
|
||||
.desc = Le fichier de configuration du panneau est manquant à cause d'une configuration personnalisée ou il est corrompu.
|
||||
|
|
@ -294,7 +294,24 @@ power = Énergie
|
|||
.desc = Gérer les paramètres d'alimentation
|
||||
|
||||
battery = Batterie
|
||||
.remaining-time = ({ $time } restant)
|
||||
.minute = { $value } { $value ->
|
||||
[one] minute
|
||||
*[other] minutes
|
||||
}
|
||||
.hour = { $value } { $value ->
|
||||
[one] heure
|
||||
*[other] heures
|
||||
}
|
||||
.day = { $value } { $value ->
|
||||
[one] jour
|
||||
*[other] jours
|
||||
}
|
||||
.less-than-minute = Moins d'une minute
|
||||
.and = et
|
||||
.remaining-time = ({ $time } jusqu'à la { $action ->
|
||||
[full] charge
|
||||
*[other] decharge
|
||||
} complète)
|
||||
|
||||
power-profiles = Modes d'énergie
|
||||
.battery = Économie d'énergie
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue